Vue v-for 为什么要加key?

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,避免使用索引,除非你确定列表不会发生变化。