day187-diff-updateChildren示例

要点

  1. updateChildren()如何进行比较最终全部替换掉的。
  • 例子:

原有的oldCh的顺序是 A、B、C、D、E、F、G

更新后成ch的顺序是 F、D、A、H、E、C、B、G

diff流程示例

开始:patchVnode (oldVnode, newVnode))

round1:(找到相同的)
对比顺序:A-F -> G-G,匹配成功,然后:
/** A-F(头头比较:不等) -> G-G(尾尾比较:相等尾部指针往前移动,不满足while条件,开始第二次循环比较) */

对G进行patchVnode的操作,更新oldEndVnodeG和newEndVnodeG的elm
指针移动,两个尾部指针向左移动,即oldEndIdx-- newEndIdx--

round2:
对比顺序:A-F -> F-B -> A-B -> F-F,匹配成功,然后:
/** (头头比较:不等) -> (尾尾比较:不等)->(头尾比较:不等)->(尾头比较:相等) */

对F进行patchVnode的操作,更新oldEndVnodeF和newEndVnodeF的elm
指针移动,移动指针,即oldEndIdx-- newStartIdx++
找到oldStartVnode在dom中所在的位置A,然后在其前面插入更新过的F的elm

round3:
对比顺序:A-D -> E-B -> A-B -> E-D,仍未成功,取D的key,在oldKeyToIdx中查找,找到对应的D,查找成功,然后:

将D取出赋值到 vnodeToMove
对D进行patchVnode的操作,更新vnodeToMoveD和newStartVnodeD的elm
指针移动,移动指针,即newStartIdx++
将oldCh中对应D的vnode置undefined
在dom中找到oldStartVnodeA的elm对应的节点,然后在其前面插入更新过的D的elm

round4:
对比顺序:A-A,对比成功,然后:

对A进行patchVnode的操作,更新oldStartVnodeA和newStartVnodeA的elm
指针移动,两个尾部指针向左移动,即oldStartIdx++ newStartIdx++

round5:
对比顺序:B-H -> E-B -> B-B ,对比成功,然后:

对B进行patchVnode的操作,更新oldStartVnodeB和newStartVnodeB的elm
指针移动,即oldStartIdx++ newEndIdx--
在dom中找到oldEndVnodeE的elm的nextSibling节点(即G的elm),然后在其前面插入更新过的B的elm

round6:
对比顺序:C-H -> E-C -> C-C ,对比成功,然后(同round5):

对C进行patchVnode的操作,更新oldStartVnodeC和newStartVnodeC的elm
指针移动,即oldStartIdx++ newEndIdx--
在dom中找到oldEndVnodeE的elm的nextSibling节点(即刚刚插入的B的elm),然后在其前面插入更新过的C的elm

round7:
获取oldStartVnode失败(因为round3的步骤4),然后:

指针移动,即oldStartIdx++

round8:
对比顺序:E-H、E-E,匹配成功,然后(同round1):

对E进行patchVnode的操作,更新oldEndVnodeE和newEndVnodeE的elm
指针移动,两个尾部指针向左移动,即oldEndIdx-- newEndIdx--

last
round8之后oldCh提前发生了‘交叉’,退出循环。

参考

VUE源码解析DIFF过程一探究竟

文章作者: lmislm
文章链接: http://lmislm.com/2019/07/19/2019-07-19/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 LMISLMのBlog