patchKeyedChildren原理

patchKeyedChildren 是在 diff 算法中对于 keyed 类型节点的处理函数。它主要用于处理同层级不同位置的子节点,即不需要移动整个子树来完成更新的情况。

其原理是通过双指针的方式,在新旧子节点数组中分别设置起始和结束的指针,然后不断移动指针进行比较和处理,最后生成一组操作序列,来完成节点的更新、插入或删除等操作。具体过程如下:

  1. 定义针对旧子节点数组和新子节点数组的四个标志位:oldStartIdx、oldEndIdx、newStartIdx 和 newEndIdx,它们分别表示当前待比较子节点在旧数组中的起始、结束索引,以及在新数组中的起始、结束索引。这些标志位会随着比较的进行而不断变化。
  2. 进行 while 循环,当旧子节点数组的开始索引小于等于结束索引且新子节点数组的开始索引小于等于结束索引时继续循环。
  3. 首先判断旧子节点数组的开始节点是否为 null/undefined,如果是则将开始索引向后移动一个位置(oldStartIdx++)。
  4. 然后判断旧子节点数组的结束节点是否为 null/undefined,如果是则将结束索引向前移动一个位置(oldEndIdx–)。
  5. 然后判断新子节点数组的开始节点是否为 null/undefined,如果是则将开始索引向后移动一个位置(newStartIdx++)。
  6. 然后判断新子节点数组的结束节点是否为 null/undefined,如果是则将结束索引向前移动一个位置(newEndIdx–)。
  7. 如果旧子节点数组的开始节点和新子节点数组的开始节点相等,则进行节点比较和更新操作,同时将开始指针向后移动一个位置(oldStartIdx 和 newStartIdx 都加1)。
  8. 如果旧子节点数组的结束节点和新子节点数组的结束节点相等,则进行节点比较和更新操作,同时将结束指针向前移动一个位置(oldEndIdx 和 newEndIdx 都减1)。
  9. 如果旧子节点数组的开始节点与新子节点数组的结束节点相等,则进行节点比较和更新操作,并将开始指针向后移动一个位置,将结束指针向前移动一个位置(oldStartIdx++,newEndIdx–)。
  10. 如果旧子节点数组的结束节点和新子节点数组的开始节点相等,则进行节点比较和更新操作,并将结束指针向前移动一个位置,将开始指针向后移动一个位置(oldEndIdx–,newStartIdx++)。
  11. 如果没有匹配的节点,就需要进行 diff 操作。将旧子节点数组中开始索引到结束索引的所有节点存储一个对象集合中,并根据 key 值生成一个键值映射表。然后遍历新的子节点数组,查找是否存在 key 值与键值映射表匹配的旧子节点。如果存在,则进行节点比较和更新操作,并将查找到的旧子节点从存储集合中删掉(对应标志位加一)。如果不存在,则认为是新节点,需要插入到正确的位置中(使用 Vue 的原生方法 insertBefore)。
  12. 循环结束后,对剩余未处理的节点和已经处理完的节点进行清理和删除操作。即对于开始索引仍小于等于结束索引的旧子节点数组,向后移动一个单位并删除节点;对于开始索引仍小于等于结束索引的新子节点数组,向后移动一个单位并插入节点。
  13. 总体来说,patchKeyedChildren 通过双指针遍历旧节点数组和新节点数组,并根据节点之间的关系生成一组操作序列,最终完成更新、插入或删除等操作。在实际场景中,该算法可以提高 diff 算法的效率,减少不必要的节点操作,提升页面性能。

你可能感兴趣的:(vue3相关文档,数据结构,算法,c++)