Vue 的 diff 算法

Vue 的 diff 算法,简而言之就是:

diff 算法的过程就是调用一个 patch 函数,去比较新旧节点,找寻差异性,并且一边比较,一边给 真实DOM 打补丁更新。
要知道渲染真实的DOM层是非常耗费资源的,比如我们修改了某个数据,要渲染到真实DOM层,就可能会引起整个DOM层的重排和重绘。
而我们又想做到“只渲染这个数据所在的一小块DOM”的目的,这个时候,diff 算法就可以帮助我们实现这个目的。
我们先根据真实DOM生成一颗virtual DOM,当virtual DOM某个节点的数据改变后会生成一个新的Vnode,然后VnodeoldVnode作对比。
发现有不一样的地方就直接修改在真实的DOM上,然后使oldVnode的值为Vnode

当数据发生改变时,set方法会让调用Dep.notify通知所有订阅者Watcher,订阅者就会调用patch给真实的DOM打补丁,更新相应的视图。
我们可以理解为有旧的Vnode数组和新的Vnode数组这两个数组

然后有四个变量充当指针分别指到两个数组的头尾

重复下面的对比过程,直到两个数组中任一数组的头指针超过尾指针,循环结束

对比两个数组的头部,如果找到,把新节点patch到旧节点,头指针后移

对比两个数组的尾部,如果找到,把新节点patch到旧节点,尾指针前移

然后互相交叉对比,旧尾新头,如果找到,把新节点patch到旧节点,并插入到正确位置,旧尾指针前移,新头指针后移

继续互相交叉对比,旧头新尾,如果找到,把新节点patch到旧节点,并插入到正确位置,新尾指针前移,旧头指针后移

都没有,开始用新指针对应节点的key去旧数组中直接找

i.如果没有key,创建新的节点

ii.如果有key并且是相同的节点,把新节点patch到旧节点,并插入到正确位置

iii.如果有key但是不是相同的节点,创建新节点

循环结束后,

1.先对比旧数组的头尾指针,如果旧数组遍历完了(可能新数组没遍历完,有漏添加的问题),添加新数组中漏掉的节点

2.再对比新数组的头尾指针,如果新数组遍历完了(可能旧数组没遍历完,有漏删除的问题),删除旧数组中漏掉的节点
原文地址:https://www.cnblogs.com/panic404/p/13627592.html