原以为这俩算法是一样的。。就只看了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值节点的比较方法;
分别对oldS、oldE、S、E
两两做sameVnode
比较,有四种值,旧集合的开头和结束(Old S Old E)新集合的开头和结束( S E),当其中两个能匹配上那么真实dom中的相应节点会移到Vnode相应的位置,这句话有点绕,打个比方
oldChild
,S
挨个和他们匹配,匹配成功就在真实dom中将成功的节点移到最前面,如果依旧没有成功的,那么将S对应的节点
插入到dom中对应的oldS
位置,oldS
和S
指针向中间移动。大意就是每次比较四个key值,匹配上的就移动,指针向后或者向前移动,都匹配不上,则遍历旧集合中有没有S,没有就添加,有就移动旧集合的S;
oldS = a, oldE = d; S = a, E = b;
oldS
和S
匹配,则将dom中的a节点放到第一个,已经是第一个了就不管了,此时dom的位置为:a b d
oldS = b, oldE = d; S = c, E = b;
oldS
和E
匹配,就将原本的b节点移动到最后,因为E
是最后一个节点,他们位置要一致,这就是上面说的:当其中两个能匹配上那么真实dom中的相应节点会移到Vnode相应的位置,此时dom的位置为:a d b
oldS = d, oldE = d; S = c, E = d;
oldE
和E
匹配,位置不变此时dom的位置为:a d b
oldS++; oldE--; oldS > oldE;
遍历结束,说明oldCh
先遍历完。就将剩余的vCh
节点根据自己的的index插入到真实dom中去,此时dom位置为:a c d b
一次模拟完成。