在 Vue 中,我们如果希望渲染一个数组,就会用到 v-for
,如:
<template>
<div class="list" v-for="item in items">
<div class="list-item" v-text="item.text"></div>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ id: 1, text: 'Entry 1' },
{ id: 2, text: 'Entry 2' },
],
};
},
}
</script>
这时,我们可以给列表中的每一个子组件绑定一个 key
,如:
<div class="list" v-for="(item, index) in items">
<div class="list-item" v-text="item.text" :key="item.id"></div>
</div>
那么问题来了,这个 key
有什么作用呢?如果不设置 key
会有什么问题呢?
key 的作用
key
其实就是给当前组件设置了一个当前上下文中的唯一标识,用于把列表子项的数据和对应的组件关联起来。
因此,列表中的 key
有以下特性:
- 不能重复,否则会导致组件和数据的关联出现混乱,无法一一映射。
- 为了方便快速查找,
key
必须为原始类型数据,不能为复杂对象。 - 默认情况下,
key
直接使用当前元素的索引,即:key="index"
。
key 的应用
举个例子,把列表中的第一项移动到整个列表的最后。假设列表中不同项的 DOM 差异较大。
如果通过 key
能让 Vue 知道他们的新位置,则只需要对应调整一下 DOM 上的元素顺序,就完成了渲染。
如果使用默认方案 :key="index"
,就地复用策略,则所有的组件都将进行 update,即组件一通过diff、DOM销毁、DOM创建、属性更新等一系列操作,终于渲染成了组件二,原来的组件二通过一系列改变渲染成了组件三,直到最后一个组件 update 成原来的组件一,开销要大很多。
实际应用中,列表中删除项、增加项、更新项应该是很常见的场景,通过绑定 key
,我们都能快速知道最佳的渲染方案,而不用对列表中每一项都重新渲染。