vue3 diff 原理
<pre><code class="language-javascript"> 新dom 旧dom
p1 p1
p3 p2
p4 p3
p2 p4
p7 p6
p5 p5</code></pre>
<pre><code class="language-javascript">先头和头比 然后 尾和尾比
新dom 旧dom
p1 p1
p3 p2
p4 p3
p2 p4
p7 p6
p5 p5</code></pre>
<pre><code class="language-javascript">构建 source 数组,它的长度等于新dom未处理节点的数量,并且初始值为-1
source 新dom 旧dom
p1 p1
-1 p3 p2
-1 p4 p3
-1 p2 p4
-1 p7 p6
p5 p5</code></pre>
<pre><code class="language-javascript">source 数组存储的是 新节点 在 旧节点 中的位置索引
source 新dom 旧dom 索引
p1 p1 0
2 p3 p2 1
3 p4 p3 2
1 p2 p4 3
-1 p7 p6 4
p5 p5 5</code></pre>
<pre><code class="language-javascript">寻找最长递增子序列(具体算法结尾有例子)
source 新dom 旧dom 索引
p1 p1 0
2 p3 p2 1
3 p4 p3 2
1 p2 p4 3
-1 p7 p6 4
p5 p5 5
这个最长递增子序列为 [1, 2]
它的含义是:在新dom中索引值为 1 和 2 的这两个节点在 dom 更新前后顺序没有发生变化
换句话说,p3 和 p4 对应的真实 DOM 不需要移动,只有 p2 和 p7 可能需要移动</code></pre>
<hr />
<h4><strong>寻找最长递增子序列</strong></h4>
<pre><code class="language-javascript">定义原数组(原数组相当于 2,3,1,-1)
原数组 7 1 6 4 5 10 8 9 0
下标 0 1 2 3 4 5 6 7 8</code></pre>
<pre><code class="language-javascript">定义结果数组,定义前驱数组
遍历原数组
如果当前项大于结果数组的最后一项,就push进去
如果当前项小于结果数组的最后一项,就从前遍历结果数组,找到第一个比当前项大的值并且替换它(贪心 + 二分)
同时记录前驱数组:每往结果数组里变更的值x1,这个值x1在结果数组的前一个值x2,x2在原数组的下标
得出以下两个数组:
前驱数组 X X 1 1 3 4 4 6 X
结果数组 0 4 5 8 9</code></pre>
<pre><code class="language-javascript">
此时用前驱数组来修正这个结果数组(反向链表):
结果数组中 9 的pre元素应该是原数组下标为 6 的元素就是 8
8 的pre元素应该是原数组下标为 4 的元素就是 5
5 的pre元素应该是原数组下标为 3 的元素就是 4
4 的pre元素应该是原数组下标为 1 的元素就是 1,此时把 0 换成 1
此时结果数组就是 1 4 5 8 9
</code></pre>