1. 为什么要加 key
?
- 唯一标识元素 :Vue 通过
key
来跟踪每个节点的身份,从而重用和重新排序现有元素。 - 提高渲染效率 :当数据变化时,Vue 会基于
key
对比新旧虚拟 DOM,只更新需要变化的元素,而非重新渲染整个列表。 - 避免状态混淆 :若没有
key
,Vue 可能会复用错误的 DOM 元素,导致表单输入框、组件状态等出现异常。
示例:
<!-- 推荐使用唯一 ID 作为 key -->
<div v-for="item in list" :key="item.id">{{ item.name }}</div>
<!-- 若数据无唯一 ID,可使用索引(不推荐,有副作用) -->
<div v-for="(item, index) in list" :key="index">{{ item.name }}</div>
2. 去掉 key
会怎样?
- 默认使用索引作为
key
:Vue 会隐式将数组索引作为key
,相当于:key="index"
。 - 潜在问题 :
- 性能下降:当列表项被插入、删除或重排序时,Vue 可能会错误地复用 DOM 元素,导致不必要的重新渲染。
- 状态异常:若列表项包含表单输入框或组件,其状态可能会错乱(例如输入内容被保留在错误的位置)。
示例(无 key
的问题):
<!-- 初始渲染 -->
<input v-for="item in list" :key="index" v-model="item.value">
<!-- 列表重排序后,输入框内容可能不会跟随数据更新 -->
3. Vue2 和 Vue3 的区别
Vue2
- 必须使用
key
:在v-for
中省略key
会触发警告。 - 不推荐使用索引作为
key
:官方明确指出使用索引作为key
可能导致性能问题和状态异常。 - diff 算法限制:Vue2 的虚拟 DOM 比较算法在处理复杂列表变化时效率较低。
Vue3
- 非强制但强烈建议 :虽然不再强制要求
key
,但官方仍强烈建议为v-for
添加唯一key
。 - 默认行为更安全 :若省略
key
,Vue3 会更保守地处理 DOM 更新,减少状态错乱的风险。 - 性能优化 :Vue3 的 diff 算法(PatchFlag)对无
key
的列表有更好的处理逻辑,但仍不如显式添加key
高效。
总结
场景 | 推荐做法 |
---|---|
列表数据稳定(不增删) | 可使用索引作为 key (仍建议用唯一 ID) |
列表数据动态变化 | 必须使用唯一 ID 作为 key |
列表项包含表单 / 组件 | 必须使用唯一 ID 作为 key |
v-for
提供唯一 key
,避免使用索引,除非你确定列表不会发生变化。