根据变更通知生成新的virtual dom树跟之前的virtual dom树进行diff & patch操作。
一、diff策略
1、按tree层级diff
2、按类型
3、列表diff——设置key,提升diff效率
二、过程分析
1、准备工作——vue定义4个指针:
OldStartIdx、OldEndIdx、NewStartIdx、NewEndIdx:
2、比较
比较的是两个指针对应的节点的vdom是否为同一个,以下比较过程中直接简写了哈~
(1)比较两个startIdx:
如果相同,则两个指针都会+1,向后移一位,再从头开始比较两个startIdx;
(2)如果两个startIdx不一致,则比较两个endIdx:
(3)如果两个endIdx一致,则两个endIdx都减1,前移一位,再执行步骤1;
(4)如果两个startIdx和两个endIdx都不一致,则比对捺向的oldStartIdx和NewEndIdx。
(5)如果捺向一致,则把oldStartIdx指向的vdom里的真实dom节点,挪到oldEndIdx位置之后。oldStartIdx加1向后移一位,newEndIdx减1向前移动一位。
(6)如果竖向和捺向都不一致,则比较撇向oldEnd和NewStart。如果撇向一致,则把oldEndIdx指向的真实dom节点挪到oldStartIdx所在的真实dom前,同时oldEndIdx减1向前移动一位,newStartIdx加1向后移动一位。
(7)如果都不一致,就看有没有key。如果有key,就能快速找到,并挪到oldStartIdx前。
(8)如果没有key,就遍历oldStartIdx和oldEndIdx之间的所有节点,寻找newStartIdx指向的节点是否存在于这些老的vdom中。如果有,就把它挪到oldStartIdx前;没有就在oldStartIdx之前创建一个节点,newEndIdx减1向前移动一位。这样比较下去,一直到newEndIdx<newStartIdx。
(9)当newEndIdx<newStartIdx,这时new vnode生成完毕,然后将old vnode中多余的部分删掉即可,也就是oldStartIdx和oldEndIdx指向的dom及中间的部分。
关注微信公众号【CC前端手记】一起学更多前端小知识吧~