key

预期:number | string | boolean (2.4.2 新增) | symbol (2.5.12 新增)
key 的特殊 attribute 主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。而使用 key 时,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。

有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误。
最常见的用例是结合v-for:

  1. <ul>
  2. <li v-for="item in items" :key="item.id">...</li>
  3. </ul>

它也可以用于强制替换元素/组件而不是重复使用它。当你遇到如下场景时它可能会很有用:

  • 完整地触发组件的生命周期钩子
  • 触发过渡

例如

  1. <transition>
  2. <span :key="text">{{ text }}</span>
  3. </transition>

当 text 发生改变时, 总是会被替换而不是被修改,因此会触发过渡。

用 key 管理可复用的元素

Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做除了使 Vue 变得非常快之外,还有其它一些好处。例如,如果你允许用户在不同的登录方式之间切换:

  1. <template v-if="loginType === 'username'">
  2. <label>Username</label>
  3. <input placeholder="Enter your username">
  4. </template>
  5. <template v-else>
  6. <label>Email</label>
  7. <input placeholder="Enter your email address">
  8. </template>

那么在上面的代码中切换 loginType 将不会清除用户已经输入的内容。因为两个模板使用了相同的元素, 不会被替换掉——仅仅是替换了它的 placeholder。

Vue 为你提供了一种方式来表达“这两个元素是完全独立的,不要复用它们”。只需添加一个具有唯一值的 key attribute 即可。

  1. <template v-if="loginType === 'username'">
  2. <label>Username</label>
  3. <input placeholder="Enter your username" key="username-input">
  4. </template>
  5. <template v-else>
  6. <label>Email</label>
  7. <input placeholder="Enter your email address" key="email-input">
  8. </template>

注意,

维护状态

当 Vue 正在更新使用v-for渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。这个类似 Vue 1.x 的track-by=”$index”。
这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一key attribute:

  1. <div v-for="item in items" v-bind:key="item.id"><!-- 内容 --></div>

建议尽可能在使用v-for时提供key attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。
因为它是 Vue 识别节点的一个通用机制,key并不仅与v-for特别关联。后面我们将在指南中看到,它还具有其它用途。

不要使用对象或数组之类的非基本类型值作为v-for的key。请用字符串数值类型的值。