diff算法

1、同层对比

diff算法只会同层对比,是深度优先

2、对比流程

  1. 数据改变触发setter,通知所有订阅者,订阅者门通过调用patch更新补丁
  2. patch
    1. 对比是否标签相同,托相同patchVnode对比下一层
  3. patchVnode(判断子节点一方有一方无)
    1. 判断newVnodeoldVnode是否指向同一个对象,如果是,那么直接return
    2. 如果他们都有文本节点并且不相等,那么将el的文本节点设置为newVnode的文本节点。
    3. 如果oldVnode有子节点而newVnode没有,则删除el的子节点
    4. 如果oldVnode没有子节点而newVnode有,则将newVnode的子节点真实化之后添加到el
  4. updateChildren(两方都有子节点,用首尾指针)
    1. 1、oldS 和 newS 使用sameVnode方法进行比较,sameVnode(oldS, newS)
    2. 2、oldS 和 newE 使用sameVnode方法进行比较,sameVnode(oldS, newE)
    3. 3、oldE 和 newS 使用sameVnode方法进行比较,sameVnode(oldE, newS)
    4. 4、oldE 和 newE 使用sameVnode方法进行比较,sameVnode(oldE, newE)
    5. 5、如果以上逻辑都匹配不到,再把所有旧子节点的 key 做一个映射到旧节点下标的 key -> index 表,然后用新 vnode 的 key 去找出在旧节点中可以复用的位置。

接下来就以上面代码为例,分析一下比较的过程

分析之前,请大家记住一点,最终的渲染结果都要以newVDOM为准,这也解释了为什么之后的节点移动需要移动到newVDOM所对应的位置

  • 第一步
oldS = a, oldE = c
newS = b, newE = a

比较结果:oldS 和 newE 相等,需要把节点a移动到newE所对应的位置,也就是末尾,同时oldS++newE--

  • 第二步
oldS = b, oldE = c
newS = b, newE = e

比较结果:oldS 和 newS相等,需要把节点b移动到newS所对应的位置,同时oldS++,newS++

  • 第三步
oldS = c, oldE = c
newS = c, newE = e

比较结果:oldS、oldE 和 newS相等,需要把节点c移动到newS所对应的位置,同时oldS++,newS++

  • 第四步

oldS > oldE,则oldCh先遍历完成了,而newCh还没遍历完,说明newCh比oldCh多,所以需要将多出来的节点,插入到真实DOM上对应的位置上

React的diff与vue的diff

reactdiff:是单端,ABCD-》DABC

遍历新节点:D

查找老节点是否复用:A。B。C。D找到D

新节点:A

找到老节点:A,移动到D后边

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值