在 Vue 中,key 的作用是帮助框架高效地识别和复用 DOM 节点或组件实例。使用数组索引 (index) 作为 key 值可能会导致以下问题,因此通常不建议这样做:
1. 列表数据变化时,可能导致错误的 DOM 复用
问题:当列表的顺序改变(如排序、插入、删除)时,Vue会基于key
复用已有的组件/DOM节点。如果是key
是index
,Vue会认为“相同索引”的节点是同一个,但实际上它们可能对应不同的数据。
示例:
// 初始列表
items: [
{ id: 1, text: "A" }, // index: 0
{ id: 2, text: "B" }, // index: 1
]
// 删除第一项后,列表变为:
items: [
{ id: 2, text: "B" }, // index: 0
]
- 如果
key
是index
,Vue会复用原来的index=0
的节点(原本是A
),但实际数据已经变成了B
,导致渲染错误(如残留的状态、错误的子组件更新)。
2. 性能问题
- 问题:当列表中间插入或删除项时,
index
会整体变化,导致Vue误判需要更新的范围,可能触发不必要的组件销毁/重建(而非复用)。 - 示例:
// 初始列表
items: ["A", "B", "C"] // index: 0, 1, 2
// 在头部插入 "D" 后:
items: ["D", "A", "B", "C"] // index: 0, 1, 2, 3
- 所有
key
(即index
)都会变化,Vue可能认为整个列表需要重新渲染,而非复用已有的A/B/C
节点。
3. 状态混乱(尤其是表单组件)
- 问题:如果子组件是有状态的(如输入框、复选框等),复用错误的组件实例会导致状态绑定到错误的项。
- 示例:
<ul>
<li v-for="(item, index) in items" :key="index">
<input type="checkbox" /> {{ item.text }}
</li>
</ul>
如果删除第一项,原本第二项的复选框状态会错误地保留在第一项上。
✅ 正确做法:使用唯一标识作为 key
- 用数据中的唯一字段(如
id
、uuid
等)作为key
,确保数据变化时Vue能精准识别节点的对应关系:
<template v-for="item in items" :key="item.id">
<ChildComponent :item="item" />
</template>
- 优点:
- 数据顺序变化时,Vue能正确复用组件/DOM。
- 避免状态绑定错乱。
- 提升渲染性能。
何时可以用 index 作为 key?
- 当列表是静态的(不会排序、增删),且子组件无状态时,可以用 index。但这种情况较少。