前言
Vue 中的 key 是用来做什么的?为什么不推荐使用 index 作为 key?常常听说这样的问题,本篇文章带你从原理来一探究竟。
本文的结论对于性能的毁灭是针对列表子元素顺序被改变、或者子元素被删除的特殊情况,提前说明清楚。
本篇已经收录在 Github 仓库,欢迎 Star:
示例
以这样一个列表为例:
<ul>
<li>1</li>
<li>2</li>
</ul>
复制代码
那么它的 vnode
也就是虚拟 dom 节点大概是这样的。
{
tag: 'ul',
children: [
{ tag: 'li', children: [ { vnode: { text: '1' }}] },
{ tag: 'li', children: [ { vnode: { text: '2' }}] },
]
}
复制代码
假设更新以后,我们把子节点的顺序调换了一下:
{
tag: 'ul',
children: [
+ { tag: 'li', children: [ { vnode: { text: '2' }}] },
+ { tag: 'li', children: [ { vnode: { text: '1' }}] },
]
}
复制代码
很显然,这里的 children
部分是我们本文 diff
算法要讲的重点(敲黑板)。
首先响应式数据更新后,触发了 渲染 Watcher
的回调函数 vm._update(vm._render())
去驱动视图更新,
vm._render()
其实生成的就是 vnode
,而 vm._update
就会带着新的 vnode
去走触发 __patch__
过程。
我们直接进入 ul
这个 vnode
的 patch
过程。
对比新旧节点是否是相同类型的节点:
1. 不是相同节点:
isSameNode
为false的话,直接销毁旧的 vnode
,渲染新的 vnode
。这也解释了为什么 diff
是同层对比。
2. 是相同节点,要尽可能的做节点的复用(都是 ul
,进入
以上内容来自于网络,如有侵权联系即删除
相关文章

上一篇: 一枚前端开发组组长的述职报告
下一篇: vue项目打包上线