在 Vue 3 中,:key 属性(或 v-bind:key)是一个特殊的属性,主要用于 v-for 列表渲染场景。它是 Vue 虚拟 DOM diff 算法的“提示”,帮助 Vue 更准确地跟踪每个节点的身份(identity)。
主要作用
-
优化列表更新性能:
- 当列表数据发生变化(如添加、删除、排序)时,Vue 需要比较新旧虚拟 DOM 节点(VNode),决定哪些节点可以复用、哪些需要移动、更新或销毁。
- 没有 key 时:Vue 默认采用“就地复用”(in-place patch)策略。它会尽量在原位置复用相同类型的元素,只更新内容。这在简单列表中高效,但如果列表顺序变化或依赖子组件状态/临时 DOM 状态(如输入框值、焦点),会导致问题:元素状态错乱、动画异常等。
- 有 key 时:Vue 根据 key 的唯一值精确匹配节点:
- 相同 key 的节点会被复用并修补(patch)。
- key 变化或不存在的节点会被移动、移除或重新创建。
- 这能最小化 DOM 操作,提高更新效率,尤其在复杂列表中。
-
维护组件/元素状态:
- 对于包含输入框、子组件等的列表,key 确保状态(如输入值、选中状态)正确绑定到对应数据项,避免因就地复用导致状态“串位”。
-
其他用途:
- 可以强制替换元素/组件(key 改变时,Vue 会销毁旧节点并创建新节点,触发生命周期钩子或过渡动画)。
- 在相同标签的过渡切换中,帮助 Vue 区分不同元素,否则只替换内部属性而不触发过渡。
使用建议(Vue 3 官方推荐)
- 始终为 v-for 提供 key,除非列表非常简单且不依赖状态。
- key 必须是唯一且稳定的值:
- 优先使用数据项的唯一 ID(如
item.id)。 - 避免使用数组索引(
index),因为插入/删除时索引会变,导致不必要的重新渲染或状态错乱。 - 不要用对象/数组等非原始值作为 key。
- 优先使用数据项的唯一 ID(如
- 示例:
<ul> <li v-for="item in items" :key="item.id"> {{ item.name }} </li> </ul> - 对于
<template v-for>(多根节点),key 必须放在<template>上(Vue 3 要求):<template v-for="item in items" :key="item.id"> <div>...</div> <span>...</span> </template>
Vue 3 与 Vue 2 的区别
- v-if/v-else/v-else-if 分支不再需要手动 key(Vue 3 自动生成唯一 key)。
- 如果手动提供 key,各分支必须唯一,不能用相同 key 强制复用。
总之,:key 是 Vue 高效渲染列表的核心机制,能显著提升性能并避免常见 bug。官方文档强烈建议在 v-for 中使用它。