每日学习计划(Vue)

每日学习计划(Vue)

  • 1、nextTick是什么?
  • 2、如何在created中操作DOM?
  • 3、Vue事件绑定原理?
  • 4、Vue模板编译原理?
  • 5、虚拟DOM以及key属性的作用?
  • 6、Vue的diff算法?

每日学习计划(Vue)_第1张图片

1、nextTick是什么?

用于下次DOM更新循环结束之后执行延迟回调。
原理:nextTick会根据执行环境分别尝试采用:

  • Promise.then
  • MutationObserver
  • setImmediate
  • 如果执行环境都不支持以上API,则采用setTimeout (fn, 0) 代替。

2、如何在created中操作DOM?

由于created执行时,DOM元素还未生成,如果在此时操作DOM会出现错 误,可以在mounted生命周期或使用nextTick操作DOM。

  • mounted中DOM元素已经生成,所以此时可以对DOM进行操作
  • 使用Vue.nextTick,通过nextTick,回调函数将在DOM更新完成后被调用。
<div id="app">{{ message }}div>
var vm = new Vue({
            el: '#app',
            data: {
                message: 'message'
            },
            created(){
                // console.log(this.$el.textContent); // 此时获取DOM元素会报错,因为DOM元素还未生成
                this.$nextTick(function() {
                    // 通过nextTick延迟执行
                    console.log(this.$el.textContent); // message;
                })
            }
        })
// 如果基于更新数据后需要对DOM进行操作的,也可以通过nextTick进行操作
var vm = new Vue({
	el: '#app',
	data: {
		message: 'old message'
	}
})

vm.message = 'new message';
// DOM未更新
console.log(vm.$el.textContent); // old message;

vm.$nextTick(function () {
	// DOM已更新
	console.log(vm.$el.textContent); // new message;
})

3、Vue事件绑定原理?

Vue事件绑定分为两种情况:

  1. 原生事件绑定:通过addEventListener绑定给真实元素。
  2. 组件事件绑定:通过Vue自定义的$on绑定组件元素

4、Vue模板编译原理?

Vue模板编译就是将template转化为render函数的过程。主要分为以下三个过程:

  1. 解析模板,生成抽象语法树(AST)
  2. 优化,有些数据不是响应式的,在首次渲染后就不会再变化了(静态节点),优化过程就是深度遍历AST语法树,对这类节点进行标记,被标记的静态节点会跳过它们的对比
  3. 编译,将优化后的AST语法树转换为可以执行的代码

5、虚拟DOM以及key属性的作用?

由于在浏览器中操作真实DOM是需要很大的性能开销的,频繁的操作真实DOM,会造成性能问题。这就是虚拟DOM的产生原因。

  1. 一个包含节点和子节点描述信息的对象,称之为虚拟节点(VNode)。
  2. 虚拟DOM是由整个Vue组件树建立起来对整个VNode树的称呼。
  3. 通过虚拟DOM隐射到真实DOM需要经历VNode的create,diff,patch等过程。
  4. 如果有事件发生修改了虚拟DOM,会比较两个虚拟DOM树的差异,得到差异对象
  5. 把差异对象重新应用到真实DOM树上

key主要作用是为了更高效的更新虚拟DOM

  1. 如果添加了key值,Vue在做Diff的时候会进行差异化对比,即通过key查询新老集合中相同的节点,相同的节点如果位置不同,不会进行节点的删除和创建,只需对位置进行移动即可。

6、Vue的diff算法?

Diff算法主要有以下过程:

  1. Diff只会对同层级进行比较,不会跨层级比较(比较后会出现四种情况)
    1、此节点是否被移除 => 添加新的节点
    2、属性是否被更改 => 旧属性改为新属性
    3、文本内容被改变 => 旧内容改为新内容
    4、节点结构不同 => 移除整个节点替换新节点

  2. 比较都有子节点的情况

  3. 递归比较子节点


Vue2.x的Diff源码基于snabbdom库,新旧两个children采用的是双端比较的算法,同时从新旧两端开始进行比较,借助key值查找可复用的节点,再进行相关操作。


Vue3.x的Diff算法和2.x有所不同,大致的变化如下:

  1. 比较新旧两个children时,会有一个预处理的过程。
    1、首先从前向后比较,当节点不同时,停止。接着又从后向前比较,当节点不同时,停止。
    2、经过预处理之后,得到的部分为真正需要进行Diff的部分。
    3、最后利用动态规划的思想,得到 “最长递增子序列” ,完成差异部分的比较。
// 预处理过程,找出差异部分
oldVDOM: a,b,[ c,d ],e,f,g
newVDOM: a,b,[ e,d,j,k ],e,f,g

// 差异部分,需要进行Diff的部分
oldVDOM: [ c,d ]
newVDOM: [ e,d,j,k ]

你可能感兴趣的:(vue)