Vue中的diff算法
diff 简介
diff 算法是一种优化手段,将前后两个模块进行差异化对比,修补(更新)差异的过程叫做patch(打补丁)
为什么 vue ,react 这些框架中都会有 diff 算法呢?要知道渲染真实 DOM 的开销是很大的,比如有时候我们修改了某个数据,如果直接渲染到真实 DOM 上会引起整个 DOM 树的重绘和重排,有没有可能我们只更新我们修改的那一小块 DOM 而不要更新整个 DOM 呢?diff 算法能够帮助我们。
当数据发生变化时,vue是怎么更新节点的?
我们先根据真实 DOM 生成一棵 virtual DOM
(虚拟DOM)树,当 virtual DOM
某个节点的数据改变后会生成一个新的 Vnode
(虚拟节点),然后 Vnode
和 oldVnode
作对比,发现有不一样的地方就直接修改在真实的 DOM 上,然后使 oldVnode
的值为Vnode
。
diff 的过程就是调用名为 patch 的函数,比较新旧节点,一边比较一边给真实的 DOM 打补丁。
virtual DOM(虚拟DOM)
// 真实dom
<div>
<p>Hello World</p>
</div>
转换成虚拟节点 类似于下面这种(伪代码)
const Vnode = {
tag:'div',
children:[
{tag:'p',text:'Hello World'}
]
}
diff 的比较方式
在采取 diff 算法比较新旧节点的时候,比较只会在同层级进行, 不会跨层级比较。
<div>
<p>123</p>
</div>
<div>
<span>456</span>
</div>
上面的代码会分别比较同一层的两个div以及第二层的p和span,但是不会拿div和span作比较。
一张很形象的图:(比较只会在同层级进行, 不会跨层级比较
)
概括起来就是对操作前后的dom树同一层的节点进行对比,一层一层对比,然后再插入真实的dom中,重新渲染
vue for 循环中 key 的作用
vue中列表循环需加:key="唯一标识"
唯一标识可以是 item
里面 id
、 index
等
因为vue组件高度复用增加 Key 可以标识组件的唯一性,那么 Key 是如何更高效的更新虚拟 DOM 的呢,我们看下面的例子:
我们希望可以在B和C之间加一个F,diff 算法默认执行起来是这样的:即把C更新成F,D更新成C,E更新成D,最后再插入E,是不是很没有效率?
所以我们需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点。
为什么不建议用index作为key?
不建议 用 index
作为 key,和没写基本上没区别,因为不管你数组的顺序怎么颠倒,index 都是 0, 1, 2 这样排列,导致 Vue 会复用错误的旧子节点,做很多额外的工作
本文作者:猫老板的豆
本文链接:https://www.cnblogs.com/bingcola/p/16499179.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步