1,diff
解释:对比新旧虚拟DOM树,完成对真实DOM的更新,这个对比差异的过程叫做 diff。
Vue 会在内部的 patch 函数中完成该过程。
diff 的时间点
当组件创建时,或依赖的数据变化时,会运行一个特定的函数来做2件事:
- 运行
_render函数生成新的 VNode tree(虚拟DOM树) - 运行
_update函数,传入新的 VNode tree 的根节点,对比新旧2个树,最终完成对真实DOM的更新。
代码表示大致逻辑:
// vue构造函数
function Vue(){
// ... 其他代码
var updateComponent = () => {
this._update(this._render())
}
new Watcher(updateComponent);
// ... 其他代码
}
diff 就发生在_update函数的运行过程中。
Watcher 的作用:简单来说,运行传入的函数(updateComponent),对函数中用到的响应式数据进行依赖收集。
Watcher的作用具体参考Vue2-数据响应式原理
2,_update 函数
-
_update函数接收一个VNode参数,也就是this._render()返回的新生成的虚拟 DOM 树。 -
_update函数通过当前组件的this._vnode属性,拿到旧的虚拟 DOM 树。 -
_update函数首先会给组件的this._vnode属性重新赋值,让它指向新树。再判断旧树是否存在:- 不存在,说明是第一次加载组件,则通过
patch函数直接遍历新树,为每个节点生成真实的DOM,并挂载到每个节点的elm属性上。(虚拟节点通过elm属性指向绑定的真实DOM。) - 存在,说明之前已经渲染过组件,则通过
patch函数对新旧树对比,来实现2个目标:- 完成对所有真实 DOM 的最小化处理。
- 让新树的节点对应合适的真实DOM。
- 不存在,说明是第一次加载组件,则通过
不存在的流程:

存在时的流程:

// 伪代码表示:
function update(vnode) {
// 参数是新 vnode
const oldVnode = this._vnode
this._vnode = vnode
}
这样就完成了组件的虚拟DOM树的更新。
但还需要解决真实的 DOM 更新(如果不考虑效率,直接用新树生成真实DOM即可)。而为了提升效率,需要对比新旧树,通过实现下面2个目标来提升效率。这个步骤在 _patch 函数中实现。
- 完成对所有真实 DOM 的最小化处理。
- 让新树的节点对应合适的真实DOM。
3,_patch 函数(进行 diff)
先来介绍几个术语,方便后续阅读:
- 【相同】:指2个虚拟节点的标签(
tag)类型、key值均相同。input元素还需要考虑type属性。<

最低0.47元/天 解锁文章
1380

被折叠的 条评论
为什么被折叠?



