vue-diff算法

处理流程

  1. 处理头部的同类型节点
  2. 处理头部的同类型节点
  3. 处理头尾/尾头同类型的节点
  4. 处理新增的节点
  5. 处理更新的节点
  6. 处理需要删除的节点

图示

1
2
3
vdom前 [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]

vdom后 [ 1, 9, 11, 7, 3, 4, 5, 6, 2, 10 ]

第一步 设置初始化值

vdom前设置指针 oldLeft 指向第一个值, oldRight 指向最后一个值

1
2
oldLeft = 1;
oldRight = 10;

vdom后设置指针 newLeft 指向第一个值, newRight 指向最后一个值

1
2
newLeft = 1;
newRight = 10;

第二步 对比头部

对比oldLeft和newLeft的值相同,则指针后移动

1
2
3
4
5
6
7
oldLeft = 2;
oldRight = 10;
newLeft = 9;
newRight = 10;

[1,2,3,4,5,6,7,8,9,10]
[ 1, 9, 11, 7, 3, 4, 5, 6, 2, 10 ]

第三步 对比尾部

  1. 对比头部发现不一致

  2. 对比尾部发现一直,这里指 oldRight = 10 与 newRight = 10, 尾部指针向前移动;

    1
    2
    3
    4
    5
    6
    oldLeft = 2;
    oldRight = 9;
    newLeft = 9;
    newRight = 2;
    [1,2,3,4,5,6,7,8,9,10]
    [ 1, 9, 11, 7, 3, 4, 5, 6, 2, 10 ]

    第四步 对比头尾

  3. 对比头部发现不一致

  4. 对比尾部发现不一致

  5. 对比头尾发现一致, 则将2号位置的dom移动到oldRight之后, oldLeft向后移动一位,newRight向前移动一位

1
2
3
4
5
6
oldLeft = 3;
oldRight = 9;
newLeft = 9;
newRight = 6;
[1,3,4,5,6,7,8,9,2, 10]
[ 1, 9, 11, 7, 3, 4, 5, 6, 2, 10 ]

第五步 对比尾头,

  1. 对比头部发现不一致
  2. 对比尾部发现不一致
  3. 对比头尾发现不一致,对比尾头发现一致, 将 oldRight 复制到 oldLeft前,oldRight向前移动一位, newLeft向前移动一位
1
2
3
4
5
6
oldLeft = 3;
oldRight = 8;
newLeft = 11;
newRight = 6;
[1,9,3,4,5,6,7,8,2,10]
[ 1, 9, 11, 7, 3, 4, 5, 6, 2, 10 ]

第六步 插入新元素

  1. 对比头部发现不一致
  2. 对比尾部发现不一致
  3. 对比头尾发现不一致
  4. 对比尾头发现不一致
  5. 发现新增节点11,则在oldLeft之前插入新元素,其他保持不变
1
2
3
4
5
6
oldLeft = 3;
oldRight = 8;
newLeft = 7;
newRight = 6;
[1, 9, 11, 3, 4, 5, 6, 7, 8, 2, 10]
1, 9, 11, 7, 3, 4, 5, 6, 2, 10 ]

第七步 删除节点

  1. 对比头部节点发现不一致
  2. 对比尾部节点发现不一致
  3. 对比头尾发现不一致
  4. 对比为头发现不一致
  5. 不是新增节点,也不需要更新, 则删除节点, oldRight向前移动一位
1
2
3
4
5
6
7
oldLeft = 3;
oldRight = 7;
newLeft = 7;
newRight = 6

[ 1, 9, 11, 3, 4, 5, 6, 7, 2, 10]
[ 1, 9, 11, 7, 3, 4, 5, 6, 2, 10 ]

第八步 为头节点相同

将尾部节点制动到oldLeft, oldLeft指向不变

1
2
3
4
5
6
oldLeft = 3;
oldRight = 6;
newLeft = 3;
newRight = 6;
[ 1, 9, 11, 7, 3, 4, 5, 6, 2, 10]
[ 1, 9, 11, 7, 3, 4, 5, 6, 2, 10 ]

第九步 对比头部,发现一致走完算法流程

参考: