Vue 中 key 的原理是什么?
在 Vue 中,`key` 是一个特殊的属性,通过唯一标识追踪 vnode 的身份,优化 diff 算法以高效更新 DOM。
在 Vue 中,key
是一个特殊的属性,其核心原理是通过唯一标识追踪虚拟 DOM(vnode)的身份,优化 Vue 的 diff 算法,以实现高效的 DOM 更新。具体原理如下:
一、核心原理
- 唯一标识 vnode
key
为每个 vnode 分配一个稳定的唯一标识符。当数据变化触发重新渲染时,Vue 的 diff 算法会通过key
精准匹配新旧 vnode:- 相同
key
:复用原有真实 DOM,仅更新变化部分(如属性或内容)。 - 不同
key
:销毁旧节点,创建新节点并插入到 DOM 中。
- 相同
- 优化 diff 算法复杂度
未使用key
时,Vue 会采用“就地复用”策略(就地复用),即认为相同索引位置的元素是同一个节点,可能导致错误复用(如列表顺序变化时状态错乱)。
使用key
后,算法复杂度从 O(n³) 降至 O(n):- 通过
key
建立映射表,跳过无变化节点的比较。 - 仅对有变化的部分进行 DOM 操作(移动、更新或删除)。
- 通过
<!-- 示例:列表渲染时推荐稳定 key -->
<ul>
<li v-for="item in items" :key="item.id"></li>
</ul>
二、解决的问题
-
状态错乱
当列表中元素顺序变化时(如排序、增删),未使用key
可能导致输入框内容错位、动画失效等问题。key
确保元素身份独立,避免旧 DOM 的残留状态被错误复用。 -
性能损耗
“就地复用”策略可能引发非必要的 DOM 更新或全量刷新。通过key
精准定位变更节点,减少无效 DOM 操作。
三、最佳实践
- 必须稳定且唯一
- ✅ 使用不可变唯一标识:如数据 ID、手机号(
:key="item.id"
)。 - ❌ 避免索引(
index
):索引变化会使 Vue 错误复用节点(例如插入数据时,原索引对应元素错位)。
- ✅ 使用不可变唯一标识:如数据 ID、手机号(
- 特殊场景强制更新
为组件设置key
并绑定动态值(如时间戳),可强制组件销毁并重建以触发生命周期钩子:
<Component :key="Date.now()" />
四、底层机制:patch 算法
在 updateChildren
方法中,Vue 通过 key
调用 sameVnode
函数判断新旧 vnode 是否为同一节点:
function sameVnode(a, b) {
return a.key === b.key && /* 其他条件(如标签名) */
}
若匹配失败,则重新创建节点而非复用。