vue diff 算法
2021/3/19 8:11:22
本文主要是介绍vue diff 算法,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
diff 算法:找出虚拟dom(vnode)之间的差异,尽可能的复用节点。
当我们改变一个节点的时候,我们其实主要改了以下部分:
- 自身的属性(style 、class等等)
- 子节点
那么 diff 算法可以抽象为两部分:
- diff(找出差异)
- patch(打补丁更新dom)
举个栗子:
给定旧数组: [a,b,c,d],新数组: [e,f,g,h],找出新旧数组之间的差异。
我们约定以下名词 - 旧首(旧数组的第一个元素) - 旧尾(旧数组的最后一个元素) - 新首(新数组的第一个元素) - 新尾(新数组的最后一个元素)
一些工具函数:
sameVnode
用于判断节点是否应该复用,这里做了一些简化,实际的diff算法复杂些,这里只用tag 和 key 相同,我们就复用节点,执行patchVnode,即对节点进行修改。
function sameVnode(a, b) { return a.key === b.key && a.tag === b.tag }
createKeyToOldIdx
建立key-index的索引,主要是替代遍历,提升性能
function createKeyToOldIdx(children, beginIdx, endIdx) { let i, key const map = {} for (i = beginIdx; i <= endIdx; ++i) { key = children[i].key if (isDef(key)) map[key] = i } return map }
旧首 和 新首 对比
if (sameVnode(oldStartVnode, newStartVnode)) { patchVnode(oldStartVnode.elm, oldStartVnode, newStartVnode); oldStartVnode = oldCh[++oldStartIdx]; newStartVnode = newCh[++newStartIdx]; }
旧尾 和 新尾 对比
if (sameVnode(oldEndVnode, newEndVnode)) { //旧尾 和 新尾相同 patchVnode(oldEndVnode.elm, oldEndVnode, newEndVnode); oldEndVnode = oldCh[--oldEndIdx]; newEndVnode = newCh[--newEndIdx]; }
旧首 和 新尾 对比
if (sameVnode(oldStartVnode, newEndVnode)) { //旧首 和 新尾相同,将旧首移动到 最后面 patchVnode(oldStartVnode.elm, oldStartVnode, newEndVnode); nodeOps.insertBefore(parentElm, oldStartVnode.elm, oldEndVnode.elm.nextSibling) oldStartVnode = oldCh[++oldStartIdx]; newEndVnode = newCh[--newEndIdx]; }
旧尾 和 新首 对比,将 旧尾 移动到 最前面
if (sameVnode(oldEndVnode, newStartVnode)) { //旧尾 和 新首相同 ,将 旧尾 移动到 最前面 patchVnode(oldEndVnode.elm, oldEndVnode, newStartVnode); nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm); oldEndVnode = oldCh[--oldEndIdx]; newStartVnode = newCh[++newStartIdx]; }
首尾对比都不符合 sameVnode 的话,尝试用newCh的第一项在 oldCh 内寻找sameVnode,如果在 oldCh 不存在对应的 sameVnode ,则直接创建一个,存在的话则判断符合 sameVnode,则移动 oldCh 对应的节点,不符合 sameVnode ,创建新节点,最后 通过 oldStartIdx > oldEndIdx ,来判断 oldCh 和 newCh 哪一个先遍历完成
oldCh 先遍历完成,则证明 newCh 还有多余节点,需要新增这些节点;newCh 先遍历完成,则证明 oldCh 还有多余节点,需要删除这些节点。
总结:
1. diff 算法的核心是子节点数组对比,思路是通过首尾两端对比。
2. key的作用是:决定节点是否可以复用,建立key-index的索引,主要是替代遍历,提升性能。
这篇关于vue diff 算法的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-24Vue CLI多环境配置学习:从入门到实践
- 2024-11-24Vue CLI多环境配置学习:新手入门教程
- 2024-11-24Vue CLI学习:初学者指南
- 2024-11-24Vue CLI学习:从入门到上手的简单教程
- 2024-11-24Vue3+Vite学习:从零开始的前端开发之旅
- 2024-11-24Vue3阿里系UI组件学习入门教程
- 2024-11-24Vue3的阿里系UI组件学习入门指南
- 2024-11-24Vue3公共组件学习:新手入门教程
- 2024-11-24Vue3公共组件学习入门指南
- 2024-11-24vue3核心功能响应式变量学习