原以为这俩算法是一样的。。就只看了react的,没想到居然不一样。。。这里做一些笔记

 

react:

是将旧的虚拟dom的同一层级的key值节点作为一个集合(旧的集合)

新的虚拟dom的同一层级的key值节点作为一个集合(新集合)

 

比如 旧集合为:

a b c d

新集合为:

b  c  a d

 

比较方法为:

先遍历新的集合,判断有哪一些节点需要添加和删除;

再判断节点的移动:

遍历新的集合;判断新集合中的节点在旧集合位置是否大于之前访问过得旧节点的最大位置;

比如以上述两集合作为例子:

1.新集合的第一个元素为b,b在旧集合的位置为1(index),之前访问过得旧节点的最大位置为0,1>0;所以b节点不需要移动

2.新集合的第二个元素为c,在旧集合的位置为2,之前访问过得旧节点的最大位置为1,2>1,所以c节点不需要移动;

3.新节点第三个元素为a,在旧集合的位置为0(index),之前访问过得旧节点的最大位置为2,0<2,所以a需要移动;

4,新节点第四个元素为d,在旧集合的位置为3(index),之前访问过得旧节点的最大位置为2,3>2,所以d不需要移动;

这个就是react的key值节点的比较方法;

 

Vue的key值节点比较方法:

分别对oldS、oldE、S、E两两做sameVnode比较,有四种值,旧集合的开头和结束(Old S Old E)新集合的开头和结束( S E),当其中两个能匹配上那么真实dom中的相应节点会移到Vnode相应的位置,这句话有点绕,打个比方

  • 如果是oldS和E匹配上了,那么真实dom中的第一个节点会移到最后
  • 如果是oldE和S匹配上了,那么真实dom中的最后一个节点会移到最前,匹配上的两个指针向中间移动
  • 如果四种匹配没有一对是成功的,那么遍历oldChildS挨个和他们匹配,匹配成功就在真实dom中将成功的节点移到最前面,如果依旧没有成功的,那么将S对应的节点插入到dom中对应的oldS位置,oldSS指针向中间移动。

大意就是每次比较四个key值,匹配上的就移动,指针向后或者向前移动,都匹配不上,则遍历旧集合中有没有S,没有就添加,有就移动旧集合的S;

  • 第一步
oldS = a, oldE = d;
S = a, E = b;

oldSS匹配,则将dom中的a节点放到第一个,已经是第一个了就不管了,此时dom的位置为:a b d

  • 第二步
oldS = b, oldE = d;
S = c, E = b;

oldSE匹配,就将原本的b节点移动到最后,因为E是最后一个节点,他们位置要一致,这就是上面说的:当其中两个能匹配上那么真实dom中的相应节点会移到Vnode相应的位置,此时dom的位置为:a d b

  • 第三步
oldS = d, oldE = d;
S = c, E = d;

oldEE匹配,位置不变此时dom的位置为:a d b

  • 第四步
oldS++;
oldE--;
oldS > oldE;

遍历结束,说明oldCh先遍历完。就将剩余的vCh节点根据自己的的index插入到真实dom中去,此时dom位置为:a c d b

一次模拟完成。

 

Logo

前往低代码交流专区

更多推荐