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

zte4gxcn  于 2023-01-21  发布在  Vue.js
关注(0)|答案(3)|浏览(136)

我在几个项目中使用过vue.js,并且一直使用索引作为for循环中的键

<div v-for="(item, index) in items" :key="index"></div>

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

<div v-for="(item, index) in items" :key="item.ID"></div>
llycmphe

llycmphe1#

因为数组是可变的。如果在数组中添加或删除项,则任何给定项的索引都可以并将 * 改变 *。
您希望您的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)
    }
  }
})
<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>

注意,当单击addValue时,顶部的列表表示数组中 * trully * 所在的数组中的新数字;在按钮下面的第二个列表中,值不代表数组中的实际位置,内部值和属性值不一致。

qcbq4gxm

qcbq4gxm2#

来自Vue文档(强调我的):www.example.comhttps://vuejs.org/guide/essentials/list.html#maintaining-state-with-key
要给Vue一个提示,以便它可以跟踪每个节点的标识,从而重用和重新排序现有元素,您需要为每个项提供一个unique key属性
如果数组中任何项目的索引发生变化(例如,通过在数组末尾以外的任何位置添加/删除新项目),则Vue将失去对该项目的跟踪。
例如:

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

Vue按如下方式跟踪每个项目:

A: 0
B: 1
C: 2
D: 3

如果您从数组中删除B,Vue将按如下方式跟踪每个项目:

A: 0
C: 1
D: 2

CD的索引已经改变,所以Vue失去了对它们的跟踪,并且将从渲染输出中移除D而不是B(因为从它的Angular 来看,移除的是索引为3的项)。
这就是为什么键应该唯一地标识一个项,而索引不能做到这一点。
但是,这也意味着在某些情况下使用索引作为键是可以接受的:

  • 阵列不会更改
  • 或者,阵列将仅在末尾添加/删除项目,而不会重新排序
  • 或者物品都是一样的

如果您不能使用索引作为键,但又不能唯一标识项目(例如,列表中的某些项目是相同的),则可以使用lodash的uniqueId()

<div v-for="item in data" :key="uniqueId()">
izkcnapc

izkcnapc3#

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: [{name:'a'},{name:'b'},{name:'c'}]
  },
  methods: {
    addValue() {
      this.items = [{name:'a'},{name:6},{name:'b'},{name:'c'}];
    }
  }
})
<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.name" :key="i"></item>
  </ul>
  <button @click="addValue">AddValue</button>
  <ul>
    <item v-for="(i, index) in items" :value="i.name" :key="index"></item>
  </ul>
</div>

为了更清楚

相关问题