为什么不总是使用索引作为vue.js for循环中的键?

get*_*bro 13 javascript indexing key vue.js v-for

我已经将vue.js用于了几个项目,并且我一直使用索引作为for循环中的键

<div v-for="(item, index) in items" :key="index"></div>
Run Code Online (Sandbox Code Playgroud)

...并开始怀疑是否存在问题,因为示例通常使用项目的ID.

<div v-for="(item, index) in items" :key="item.ID"></div>
Run Code Online (Sandbox Code Playgroud)

Ber*_*ert 21

因为数组是可变的.如果在数组中添加或删除项目,则任何给定项目的索引都可以更改.

您希望自己key成为唯一标识唯一组件的值.您创建的主键总是比使用索引更好.

这是一个例子.

console.clear()

Vue.component("item", {
  props: ["value"],
  data() {
    return {
      internalValue: this.value
    }
  },
  template: `<li>Internal: {{internalValue}} Prop: {{value}}</li>`
})


new Vue({
  el: "#app",
  data: {
    items: [1, 2, 3, 4, 5]
  },
  methods: {
    addValue() {
      this.items.splice(this.items.length / 2, 0, this.items.length + 1)
    }
  }
})
Run Code Online (Sandbox Code Playgroud)
<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
<div id="app">
  {{items}}
  <ul>
    <item v-for="i in items" :value="i" :key="i"></item>
  </ul>
  <button @click="addValue">AddValue</button>
  <ul>
    <item v-for="(i, index) in items" :value="i" :key="index"></item>
  </ul>
</div>
Run Code Online (Sandbox Code Playgroud)

请注意,addValue单击时,顶部的列表表示数组中真正位于数组中的新数字; 在中间.在按钮下面的第二列表,所述值并没有在阵列中表示的实际位置和所述内部和属性值不同意.

  • @AlexAlexson组件中的data函数仅在组件的生存期内运行一次。该分配是一个初始化值。当value属性改变时,示例组件中没有任何东西会更新internalValue。 (2认同)

bin*_*unt 7

来自 Vue 文档(重点是我的):https://vuejs.org/guide/essentials/list.html#maintaining-state-with-key

为了给 Vue 一个提示,以便它可以跟踪每个节点的身份,从而重用和重新排序现有元素,您需要为每个项目提供唯一的 key属性

如果数组中任何项目的索引发生更改(例如,通过在数组末尾以外的任何位置添加/删除新项目),则 Vue 将失去对该项目的跟踪。

例如:

let data = [A, B, C, D]
<div v-for="(item, index) in data" :key="index">
Run Code Online (Sandbox Code Playgroud)

Vue 像这样跟踪每个项目:

A: 0
B: 1
C: 2
D: 3
Run Code Online (Sandbox Code Playgroud)

B如果从数组中删除,Vue 将像这样跟踪每个项目:

A: 0
C: 1
D: 2
Run Code Online (Sandbox Code Playgroud)

C和 的索引D已更改,因此 Vue失去了对它们的跟踪D,并将从渲染输出中删除B(因为从它的角度来看,删除的是索引为 3 的项目)。

这就是为什么键应该唯一地标识一个项目,而索引则不能做到这一点。


然而,这也意味着在某些情况下使用索引作为键是可以接受的:

  • 数组不会改变
  • 或者数组只会在末尾添加/删除项目,并且不会重新排序
  • 或者物品都是相同的

如果您无法使用索引作为键,但无法唯一标识项目(例如列表中的某些项目相同),解决方案可能是使用 lodash 的uniqueId()

<div v-for="item in data" :key="uniqueId()">
Run Code Online (Sandbox Code Playgroud)

或者正如这里提到的那样

<div v-for="(item, index) in data" :key="`${item.someProperty}-${index}`">
Run Code Online (Sandbox Code Playgroud)