Vue3 key 属性
key 属性是 Vue 虚拟 DOM 算法的关键特殊属性,主要用于帮助 Vue 识别每个节点的唯一性,从而高效地更新虚拟 DOM。
基本说明
key 属性用于为 Vue 组件或元素提供唯一标识。在列表渲染中,每个 v-for 循环的元素都应该有唯一的 key 属性。
- 类型: String | Number
- 作用: 在列表渲染中为每个元素提供唯一标识,帮助 Vue 高效地 diff 和复用 DOM 节点。
工作原理
当 Vue 进行虚拟 DOM diff 时,没有 key 时,Vue 会采用一种最小化元素移动的算法,尽可能地在原地复用相同类型的元素。有了 key 之后,Vue 会根据 key 的顺序变化来重新排序元素,并且会移除不再存在 key 的元素。
同一父元素的子元素必须具有唯一的 key。重复的 key 会导致渲染错误。
基本用法
最常见的用法是结合 v-for 使用:
实例
<ul>
<li v-for="item in items" :key="item.id">
{{ item.name }}
</li>
</ul>
<li v-for="item in items" :key="item.id">
{{ item.name }}
</li>
</ul>
使用场景
1、列表渲染
在 v-for 中使用 key 是最常见的场景:
实例
<template>
<div>
<div v-for="user in users" :key="user.id" :style="{ marginBottom: '10px' }">
<span>{{ user.id }}</span> -
<span>{{ user.name }}</span> -
<span>{{ user.email }}</span>
</div>
</div>
</template>
<script>
export default {
data() {
return {
users: [
{ id: 1, name: '张三', email: 'zhangsan@example.com' },
{ id: 2, name: '李四', email: 'lisi@example.com' },
{ id: 3, name: '王五', email: 'wangwu@example.com' }
]
}
}
}
</script>
<div>
<div v-for="user in users" :key="user.id" :style="{ marginBottom: '10px' }">
<span>{{ user.id }}</span> -
<span>{{ user.name }}</span> -
<span>{{ user.email }}</span>
</div>
</div>
</template>
<script>
export default {
data() {
return {
users: [
{ id: 1, name: '张三', email: 'zhangsan@example.com' },
{ id: 2, name: '李四', email: 'lisi@example.com' },
{ id: 3, name: '王五', email: 'wangwu@example.com' }
]
}
}
}
</script>
2、强制替换元素
key 还可以用于强制替换元素或组件,而不是复用它。这在以下场景中很有用:
- 正确触发组件的生命周期钩子
- 触发过渡动画
实例
<template>
<div>
<input v-model="text" placeholder="输入内容" />
<transition>
<span :key="text">{{ text }}</span>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
text: ''
}
}
}
</script>
<div>
<input v-model="text" placeholder="输入内容" />
<transition>
<span :key="text">{{ text }}</span>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
text: ''
}
}
}
</script>
当 text 变化时,<span> 元素会被替换而不是被复用,因此会触发过渡效果。
注意事项
key 应该是唯一且稳定的:key 的值不应该随着数据的变化而变化,否则会影响 Vue 的性能和虚拟 DOM 的复用策略。
避免使用索引作为 key:除非你明确知道列表项的顺序不会改变。因为索引是基于位置的,当列表顺序发生变化时,key 也会变化,导致 Vue 无法正确复用 DOM 节点。
实例
<!-- 不推荐:使用索引作为 key(列表顺序会变化时) -->
<li v-for="(item, index) in items" :key="index">{{ item.name }}</li>
<!-- 推荐:使用唯一 ID 作为 key -->
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
<li v-for="(item, index) in items" :key="index">{{ item.name }}</li>
<!-- 推荐:使用唯一 ID 作为 key -->
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
与 v-for 配合使用
key 与 v-for 配合使用时,有以下几种语法:
实例
<!-- 数组遍历 -->
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
<!-- 带索引的遍历 -->
<li v-for="(item, index) in items" :key="index">{{ index }} - {{ item.name }}</li>
<!-- 对象遍历 -->
<li v-for="(value, key, index) in object" :key="key">
{{ index }}. {{ key }}: {{ value }}
</li>
<!-- 数字遍历 -->
<span v-for="n in 5" :key="n">{{ n }}</span>
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
<!-- 带索引的遍历 -->
<li v-for="(item, index) in items" :key="index">{{ index }} - {{ item.name }}</li>
<!-- 对象遍历 -->
<li v-for="(value, key, index) in object" :key="key">
{{ index }}. {{ key }}: {{ value }}
</li>
<!-- 数字遍历 -->
<span v-for="n in 5" :key="n">{{ n }}</span>

Vue3 内置属性