接上回。
先看第一个 demo。
<!-- 更新前 -->
<ul>
<li key="jd">jingdong</li>
<li key="tx">tengxun</li>
<li key="hw">huawei</li>
<li key="xm">xiaomi</li>
</ul>
<!-- 更新后 -->
<ul>
<li key="jd">jingdong</li>
<li key="hw">huawei</li>
<li key="xm">xiaomi</li>
<li key="tx">tengxun</li>
</ul>
定义 lastPlacedIndex 表示上一次可复用节点的索引,oldIndex 表示更新前节点的索引(从 0 开始)。
如果 oldIndex 大于 lastPlacedIndex 则更新 lastPlacedIndex 为 oldIndex;如果 oldIndex 小于 lastPlacedIndex 则移动。
需要执行两轮遍历:
第一轮:
- 比较更新前后的第一个节点,
key都是jd,没有没变,可以复用,lastPlacedIndex = 0 - 比较更新前后的第二个节点,旧的
key是tx,新的key是hw,结束第一次遍历(key不同直接结束遍历)
第二轮:
- 从更新后的第二个节点
hw开始,oldIndex是 2,大于lastPlacedIndex(大于 0),可以复用,更新lastPlacedIndex为 2 - 第三个节点
xm,oldIndex是 3,大于lastPlacedIndex(大于 2),可以复用,更新lastPlacedIndex为 3 - 第四个节点
tx,oldIndex是 1,小于lastPlacedIndex(小于 3),向后移动。
结论:移动 tx,其他三个节点保持不变
注意:向后移动方向是从前向后。
再看第二个 demo,加深理解。
<!-- 更新前 -->
<ul>
<li key="jd">jingdong</li>
<li key="tx">tengxun</li>
<li key="hw">huawei</li>
<li key="xm">xiaomi</li>
</ul>
<!-- 更新后 -->
<ul>
<li key="xm">xiaomi</li>
<li key="jd">jingdong</li>
<li key="tx">tengxun</li>
<li key="hw">huawei</li>
</ul>
同样需要执行两轮遍历:
第一轮:
- 比较更新前后的第一个节点,旧
key的是jd,新的key是xm,结束第一次遍历
第二轮:
- 更新后的第一个节点
xm,oldIndex是 3,赋值lastPlacedIndex为 3 - 第二个节点
jd,oldIndex是 0,小于lastPlacedIndex(小于 3),向后移动 - 第三个节点
tx,oldIndex是 1,小于lastPlacedIndex(小于 3),向后移动 - 第四个节点
hw,oldIndex是 2,小于lastPlacedIndex(小于 3),向后移动
结论:xm 不变,其他三个节点向后移动