Vue基础(实现虚拟dom转换成真实DOM)

2022-06-27 08:18:15

Vue组件data为什么必须是个函数?

  • 每次使用组件时都会对组件进行实例化操作,并且调用data函数返回一个对象作为组件的数据源。这样可以保证多个组件间数据互不影响

nextTick在哪里使用?原理是?

nextTick中的回调是在下次 DOM 更新循环结束之后执行的延迟回调。可用于获取更新后的 DOM。Vue中数据更新是异步的,使用nextTick方法可以保证用户定义的逻辑在更新之后执行。

computed和watch区别

  • computed和watch都是基于Watcher来实现的
  • computed属性是具备缓存的,依赖的值不发生变化,对其取值时计算属性方法不会重新执行
  • watch则是监控值的变化,当值发生变化时调用对应的回调函数

Vue.set方法是如何实现的

  • 我们给对象和数组本身都增加了dep属性
  • 当给对象新增不存在的属性则触发对象依赖的watcher去更新
  • 当修改数组索引时我们调用数组本身的splice方法去更新数组

Vue为什么需要虚拟DOM

  • 由于直接操作DOM性能低但是js层的操作效率高,可以将DOM操作转化成对象操作,最终通过diff算法比对差异进行更新DOM(减少了对真实DOM的操作)。
  • 虚拟DOM不依赖真实平台环境从而也可以实现跨平台。

Vue中diff算法原理

  • Vue的diff算法是平级比较,不考虑跨级比较的情况。内部采用深度递归的方式 + 双指针的方式进行比较。
  • 1.先比较是否是相同节点 key tag
  • 2.相同节点比较属性,并复用老节点
  • 3.比较儿子节点,考虑老节点和新节点儿子的情况
  • 4.优化比较:头头、尾尾、头尾、尾头
  • 5.比对查找进行复用
  • Vue3中采用最长递增子序列来实现diff优化

请说明Vue中key的作用和原理,谈谈你对它的理解

  • Vue在patch过程中通过key可以判断两个虚拟节点是否是相同节点。(可以复用老节点)
  • 无key会导致更新的时候出问题
  • 尽量不要采用索引作为key

Vue的生命周期方法有哪些?一般在哪一步发送请求及原因

beforeCreate 在实例初始化之后,数据观测(data observer) 和 event/
watcher事件配置之前被调用。
created 实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。这里没有 e l b e f o r e M o u n t 在 挂 载 开 始 之 前 被 调 用 : 相 关 的 r e n d e r 函 数 首 次 被 调 用 。 m o u n t e d e l 被 新 创 建 的 v m . el beforeMount 在挂载开始之前被调用:相关的 render 函数首次被调用。 mounted el 被新创建的 vm.elbeforeMountrendermountedelvm.el 替换,并挂载到实例上去之后调用该钩子。
beforeUpdate 数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。
updated 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
beforeDestroy 实例销毁之前调用。在这一步,实例仍然完全可用。
destroyed Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。 该钩子在服务器端渲染期间不被调用。
keep-alive (activated 和 deactivated)

JS数组去重的几种常见方法

最简单数组去重法

  • 新建一新数组,遍历传入数组,值不在新数组就push进该新数组中
  • IE8以下不支持数组的indexOf方法
functionuniq(array){var temp=[];//一个新的临时数组for(var i=0; i< array.length; i++){if(temp.indexOf(array[i])==-1){
            temp.push(array[i]);}}return temp;}var aa=[1,2,2,4,9,6,7,5,2,3,5,6,5];
console.log(uniq(aa))

对象键值法去重

  • 速度最快, 占空间最多(空间换时间)
  • 该方法执行的速度比其他任何方法都快, 就是占用的内存大一些。
  • 现思路:新建一js对象以及新数组,遍历传入数组时,判断值是否为js对象的键,
  • 不是的话给对象新增该键并放入新数组。
  • 注意点:判断是否为js对象键时,会自动对传入的键执行“toString()”,
  • 不同的键可能会被误认为一样,例如n[val]-- n[1]、n[“1”];
  • 解决上述问题还是得调用“indexOf”。
functionuniq(array){var temp={}, r=[], len= array.length, val, type;for(var i=0; i< len; i++){
        val= array[i];
        type=typeof val;if(!temp[val]){
            temp[val]=[type];
            r.push(val);}elseif(temp[val].indexOf(type)<0){
            temp[val].push(type);
            r.push(val);}}return r;}var aa=[1,2,"2",4,9,"a","a",2,3,5,6,5];
console.log(uniq(aa));

优化遍历数组法

思路:获取没重复的最右一值放入新数组(检测到有重复值时终止当前循环同时进入顶层循环的下一轮判断)

functionuniq(array){var temp=[];var index=[];var l= array.length;for(var i=0; i< l; i++){for(var j= i+1; j< l; j++){if(array[i]=== array[j]){
                i++;
                j= i;}}
        temp.push(array[i]);
        index.push(i);}
    console.log(index);return temp;}var aa=[1,2,2,3,5,3,6,5];
console.log(uniq(aa));

1.调用render方法产生虚拟节点 虚拟DOM
2.根据虚拟DOM产生真实DOM
vue核心流程 :① 创造了响应式数据,②模板转换成ast语法树 ;
render函数会去产生虚拟节点(使用响应式数据根据生成的虚拟节点创造真实的DOM)

// h()  _c()exportfunctioncreateElementVNode(vm, tag, data,...children){if(data==null){
        data={}}let key= data.key;if(key){delete data.key}returnvnode(vm, tag, key, data, children);}// _v();exportfunctioncreateTextVNode(vm, text){returnvnode(vm,undefined,undefined,undefined,undefined,
     text);}// ast一样吗?ast做的是语法层面的转化 他描述的是语法本身(可以描述js css html)// 我们的虚拟dom 是描述的dom元素,可以增加一些自定义属性  (描述dom的)functionvnode(vm, tag, key, data, children, text){return{
        vm,
        tag,
        key,
        data,
        children,
        text// ....}}
  • 作者:DomCode
  • 原文链接:https://hejianing.blog.csdn.net/article/details/121930746
    更新时间:2022-06-27 08:18:15