为什么v-for要绑定key?

在 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,我们都能快速知道最佳的渲染方案,而不用对列表中每一项都重新渲染。


© 2020