key是虚拟节点的唯一标识,用于diff算法精准追踪节点身份;无key时Vue只能按索引就地复用,导致表单错位、动画失效、状态丢失等问题。

因为 Vue 3 的虚拟 DOM diff 算法依赖 key 来精准识别和追踪每个节点的身份。没有 key,Vue 就无法区分“同一位置的元素是否还是原来那个”,只能按索引就地复用,导致状态错乱、输入跳变、动画失效等实际问题。
key 是虚拟节点的“身份证”
Vue 渲染时会生成虚拟节点(vnode),diff 过程中需要判断新旧 vnode 是否代表同一个真实 DOM 元素。key 就是这个判断依据:
- 若两个 vnode 的 key 相同,Vue 认为它们是同一节点,直接复用并更新内容
- 若 key 不同,Vue 视为不同节点,会卸载旧节点、挂载新节点
- 没有 key 时,Vue 只能靠索引匹配——把新数组第 0 项当作旧数组第 0 项来更新,哪怕数据本身已移位
不写 key 或 key 写错的典型后果
这些不是理论风险,而是用户可感知的问题:
- 表单内容漂移:在列表中编辑第 2 项的 input,删掉第 1 项后,光标和值跑到新列表的第 1 项上
- 选中态错位:勾选了 item.id=5 的复选框,排序后发现 item.id=3 被勾上了
-
过渡动画中断:
下新增/删除项时无入场或离场动效,或动效套在错误元素上 - 组件反复重建:带内部状态的子组件(如富文本编辑器)每次列表变化都重新初始化
怎么写 key 才算正确
key 不是随便填的字符串,必须满足三个硬性条件:
立即学习“前端免费学习笔记(深入)”;
- 类型合法:只能是字符串或数字,不能是对象、数组或布尔值(否则控制台警告)
- 同一父级下唯一:兄弟节点之间 key 值不能重复,否则 Vue 无法区分
-
值稳定不变:key 必须来自数据本身的固定标识,比如
:key="item.id";禁用:key="index"或:key="Math.random()"
遍历对象时可用 :key="key"(属性名),但需确保属性名稳定;遍历数字(如 v-for="n in 5")可用 :key="n",因数量固定、顺序不变。
key 必须绑定在 v-for 所在标签上
常见错误是把 key 加在子元素上,比如:
✘ 错误写法<div v-for="item in list"><span :key="item.id">{{ item.name }}</span></div>
正确做法是 key 和 v-for 在同一标签:
✔ 正确写法<div v-for="item in list" :key="item.id">{{ item.name }}</div>
如果 v-for 渲染的是组件,key 也要放在组件标签上,且组件内部无需再设 key。


















