首页>>前端>>Vue->一文彻底搞懂Vue3源码系列之diff算法

一文彻底搞懂Vue3源码系列之diff算法

时间:2023-11-29 本站 点击:0

前言

我们上回说到,当老的是数组,新的也是数组就会进行diff算法

第一步

将老的儿子和新的儿子以及比较的是哪个元素

第二步

Vue3并没有采用双指针,都是默认从头开始比对

情况1

先定义一个变量,值设置为0,因为一开始都是从头开始比较

然后分别获取老的儿子的长度,和新的儿子的长度

写一个while循环,当i小于新的和老的任意一个长度就进行diff

循环内部分别取出对应儿子节点,然后判断新的和老的是否是同一个节点

如果一样,则调用patch深度比较他们的儿子,patch内部又会做判断,如果是元素又会调patchElement去进行比对,递归比对,又重复了前面的流程,更新props、判断是文本还是数组等,前后都是数组又进入了diff...

如果不一样就break出去,去比对下一对。这样的话我们上述图中,a和b是不是就不用管了,他们自己内部再去patch,我们本次只需要关心c、d和e去了,我们就大大缩小了比对的范围

情况2

这个时候我们应该比对的范围是前面仨,a、d和e,这个时候我们反着比就可以了

在上个while循环下面,我们继续再写个while循环,条件跟上一个循环是一样的

从尾开始取

然后判断是不是同一个节点,如果是进入patch,否则break

经历了第一个和第二个循环,中间的完全不同的就晒出来了

情况3

有一方已经比对完了,多的进行挂载

那我们怎么确定需要挂载呢?

观察两张图,得出结论,i如果比e1大就说明需要挂载,也就是i超过就需要挂载

那我们怎么确定需要挂载的是谁呢?

观察两张图,得出结论,i和e2之间的就需要插入

那我们怎么挂载呢?

调用patch方法,当patch方法第一个参数是null,也就是没有初始虚拟节点的时候,就表示插入操作

那我们怎么知道是向前插入还是向后插入呢?

我们可以去拿到e2的下一个值,如果下一个值比自己数组长度小,则说明是需要向前插入,取下一个所对应的作为参照物,向前追加。否则,是需要向后插入,那参照物设置为null,表示直接向后追加。

老的少,新的多

我们拿到了参照物后,传入patch,如果参照物有值,会插到它的前面,否则直接向最后追加进去,patch这里我们之前博客有写

老的多,新的少,需要卸载

这又会出现两种情况,卸载前面的还是后面的

我们怎么知道要删除呢?

如果i比e2大,就表示要进行删除操作,删除i和e1之间元素

第三步

乱序比较,前后完全没有关系

需要尽可能的复用,用新的元素做成一个映射表去老的里面找,一样的就复用,不一样的要不就插入,要不就删除

中间情况就是乱序需要比较的地方

创建s1和s2

把新的做一个映射表,遍历s2和e2里面的元素

把里面的每一个放到map里

去老的里面查找,看有没有复用的,老的区间是s1-e1

如果老的在新的映射表里找不到,说明,老的里的不在新的中,就把老的删掉

如果找到了,就比对两个

上述乱序完毕之后还有两个问题,一个是是位置问题,一个是新增节点的插入问题

第四步

我们来分析乱序比对中的两个问题,位置移动和新增插入,因为乱序中如果两个匹配上了,我们只是做了比对,并没有移动,并且也没有处理新增的情况

我们用一个数组把新的中需要比对的个数存一下,也就是e2-s2+2

我们需要把新的索引和老的索引做一个映射,生成一个数组,初始值设置为0

我们每次patch过的改成0,最后数组中是0的就是没patch的

在新老比对的时候,去赋值处理

newIndex -前面的ab不属于乱序中的,也就是s2

然后我们就可以通过这个数组知道没有被patch的元素了,也就是新增的元素

倒序循环数组,从后开始取,这个i要加上s2,这样才是真实的位置

如何插呢?找到下一个元素,如果下一个元素存在,就插到它的前面,如果不存在是null,则直接插入,这个思想在前面也有用。我们这里通过当前下标jia1,来和整个length比对

然后我们从数组中取出中间的元素,看看是不是0,如果是0,则是没有被patch过

调用patch方法,第一个参数是null表示新增,把容器和参照物传入

然后如果被patch过,直接插入,以下一个作为参照物

倒序插入

可能有人有疑问,我们在哪里复用老的元素了?

在新老比对的时候,老的节点在新的里面,就会进行patch操作,这个patch操作就是复用,更新属性,比较儿子

优化

我们上述操作需要将节点全部的移动一遍,我们希望尽可能少的移动,我们只需要找联系最长的,只需要动不连续的,这就是最长递增子序列

下回我们开始分析最长递增子序列

如果您觉得有所收获,麻烦动动小手点个攒,谢谢啦~ 预知后事如何,且听下回分解~


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/Vue/849.html