在js中,渲染真实Dom的开销是非常大的,比如我们修改了摸某个数据,如果直接渲染到真实的Dom上会引起整个dom树的重绘和回流,那么有没有可能实现只更新我们修改的那一小块dom,而不是整个dom呢?此时我们就需要先根据真是的dom生成虚拟的dom ,当虚拟的dom某个节点的数据改变后会生成一个新的Vnode,然后新的Vnode和旧的Vnode作比较,发现有不一样的地方就直接修改在真实Dom上,然后新的Vnode的值替换旧的Vnode的值
diff的过程就是调用path函数,比较旧节点,一边比较一边给真实的DOM打补丁。在采取diff算法比较新旧节点的时候,比较只会在同层级进行。在patch方法中首先树级别的比较 new Vnode 不存在就删除 old Vnode, old Vnode不存在就增加新的Vnode, 都存在就执行diff更新,当确定需要执行diff算法时,比较两个Vnode,包括三种类型操作: 属性更新,文本更新,子节点更新 新老节点均有子节点,则对子节点进行
diff
操作,调用updatechidren
如果老节点没有子节点而新节点有子节点,先清空老节点的文本内容,然后为其新增子节点 如果新节点没有子节点,而老节点有子节点的时候,则移除该节点的所有子节点 老新老节点都没有子节点的时候,进行文本的替换
updateChildren 将
Vnode
的子节点Vch和oldVnode的子节点oldCh提取出来。oldCh和vCh
各有两个头尾的变量StartIdx和EndIdx
,它们的2个变量相互比较,一共有4种比较方式。如果4种比较都没匹配,如果设置了key
,就会用key
进行比较,在比较的过程中,变量会往中间靠,一但StartIdx>EndIdx
表明oldCh和vCh
至少有一个已经遍历完了,就会结束比较。