写在前面,笔记来源于www.bilibili.com/video/BV1iX… 侵删
diff算法提出的四种命中查找,四个指针
①新前与旧前
新前:新的虚拟节点中所有没有处理的开头的节点
旧前:旧的虚拟节点中所有没有处理的开头的节点
②新后与旧后
新后:新的虚拟节点中所有没有处理的结尾的节点
旧后:旧的虚拟节点中所有没有处理的结尾的节点
③新后与旧前
④新前与旧后
需要注意的事,这样的查找方式并不是snabbdom独创的查找方式,但是是diff的经典的算法优化策略,也是diff传统的优化策略。
要注意的是,这里的顺序是从上往下的,如果查找到①了,就不会再往下走了
命中①就不会往下走了,以此类推
新增:
旧前->新前 匹配
旧前->新前 匹配
旧前->新前 匹配
旧节点结束,新节点没有结束,新节点剩下的节点直接追加到dom就好
删除:
旧前->新前 匹配
旧前->新前 匹配
旧前->新前 不匹配 ====按照匹配规则==>旧后,新后
旧后->新后 匹配
此时旧节点没结束,新节点已经结束,说明剩下的是要被删除的节点
(再次强调,新前旧前=>新后旧后=>新后旧前=>新前旧后,按照顺序来)
新前->旧前(AA) 匹配
新前->旧前(BB) 匹配
新前->旧前(CD) 不匹配==更改为新后旧后==>
新后->旧后(DE) 不匹配==更改为新后旧前==>
新后->旧前(DC) 不匹配==更改为新前旧后==>
新前->旧后(DE) 不匹配
四个都不匹配!!
如果都没命中,就需要用循环来进行寻找命中了
循环旧节点,找key为D的,发现:
循环找到结果了===>先判断成移动位置,
虚拟dom打undefined标志,真实dom移动位置====>循环新节点,
发现新节点结束了(这里老师讲的也有问题),
说明剩下的是要被删除掉的节点,将其他的节点删掉,所以CE被删除掉了
剩余节点就是旧前和新后指针卡住的节点(中间的节点)
比较复杂的情况
新前->旧前(AE) 不匹配 ==更改为新后旧后==>
新后->旧后(EM) 不匹配 ==更改为新后旧前==>
新后->旧前(AM) 不匹配 ==更改为新前旧后==>
新前->旧后(EE) 匹配 (④命中了)
当新前旧后(④)命中
意味着 新前旧后(EE) 匹配到以后 旧节点虚拟节点中的E被标识undefined了,
E在真实dom节点中出现在了旧前(此时可能旧前前面匹配到了,可能没被匹配,
换而言之,就是出现在了没被处理没被匹配到的旧节点的前面了!!)的前面了。
也就是说,此时E出现在了真实dom的第一个位置
也就是说,假设在匹配到情况④之前前三个有被匹配到的话,那么此时E出现在匹配好的节后
没被匹配的节点前
继续往下走:
新前->旧前(CA) 不匹配
新后->旧后(MD) 不匹配
新后->旧前(MB) 不匹配
新前->旧后(CD) 不匹配
循环
在旧节点中找C==>找到了:
给虚拟节点C加上undefined标识,将真实domC放到没被匹配到的节点最前面(也就是E后面)也就是旧前之前
当前真实dom:EC
(不知道未来的我还能不能看懂!自信点!!!现在看懂了将来的我一定也能看懂!!)
继续往下走:
新前->旧前(MA) 不匹配
新后->旧后(MD) 不匹配
新后->旧前(MA) 不匹配
新前->旧后(MD) 不匹配
循环
在旧节点(ABD)中寻找M==>没找到==>把M插入到旧前之前(没被处理的节点前)
新节点处理结束了
老节点还有剩余==>说明需要删除节点
更复杂的情况
新前->旧前(AE) 不匹配==更换为新后旧后==>
新后->旧后(EA) 不匹配==更换为新后旧前==>
新后->旧前(AA) 匹配
同样的道理,也是会移动节点,将虚拟节点标识为undefined,移动到真实dom那边
移动旧前A到老节点的旧后后面
继续
新前旧前(BE) 不匹配
新后旧后(BE) 不匹配
新后旧前(BB) 匹配
虚拟节点B标识undefined,真实domB移动到旧后之后
(注意旧后只能时候从后往前走)
.....
同理
如果最后发现新节点那边多了一个,就往旧后之后追加
贴心的邵老师给了个小总结:
③情况命中的前提下,旧前就是新后啦。
同样的道理,④情况命中的前提下,新前就是旧后啦~