diff算法

88 阅读2分钟

专门用来对比新旧虚拟dom

本质上对比两个js对象差异(虚拟dom就是js对象)

数据改变时,触发setter,触发dep.notify方法,通知各数据使用方(所有订阅者watcher),执行patch方法

patch方法接收新旧虚拟节点两个参数,先判断是否为同类标签,如果不是同类标签,直接替换就行

如果是同类标签,需要执行patchvnode方法,这个方法可以对比一下新旧虚拟节点是否相等,如果相等,直接return。

如果不相等,需要分情况比对,比对的原则就是以新的虚拟节点为准,第一种情况是旧虚拟节点和新虚拟节点都有文本节点,直接新文本替换旧的文本,

第二种,旧的没有子节点,新的有子节点,直接添加子节点就可以了,

第三种,旧的有子节点,新的没有子节点,直接删除旧的子节点,

第四种,新旧都有子节点,这样需要比对他们的子节点,内部有一个updatechildren方法,专门对比他们的子节点,

image.png (一段新旧虚拟dom,方法内部规定只在同级比对,减少比对次数,最大化的提高比对性能,同级比对的时候采用收尾指针法,首先就虚拟节点的start和新虚拟节点的start作比对,如果没有比对成功,就虚拟节点的start和新虚拟节点end,没有成功,就虚拟杰节点的end和新虚拟节点的start,没成功就虚拟节点的end和新虚拟节点的end作比对,依照以上顺序,当比对成功,退出当前比对渲染结果以新虚拟节点的结果为准,每次比对成功后,比对成功的start会向右侧移动,end会向左侧移动,当start跑到end右边就终止比较,如果首尾指针法以上四种情况都没有比对成功的话,则会看新旧虚拟节点的key值,如果他们的key值有相同的,就会复用,并依照新虚拟节点的位置,移动到相应位置上去,)

image.png