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

IT技术 javascript indexing vue.js key v-for
2021-01-24 16:42:29

我已经在几个项目中使用了 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>
2个回答

因为数组是可变的如果项目被添加到数组或从数组中删除,任何给定项目的索引都可以并且将会改变

您希望您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单击时,顶部的列表表示数组中真正在数组中的新数字在中间。在按钮下面的第二列表,所述值并没有在阵列中表示的实际位置和所述内部和属性值不同意。

@getsetbro 有一些方法可以缓解使用索引作为键时出现的问题,并且可能在某些情况下索引是您的唯一选择,但理想的情况是使用正确的键。
2021-03-26 16:42:29
谢谢你的例子。我从中学到的是 key 属性允许 Vue 正确跟踪项目在数组中的位置并相应地呈现。但是,我不明白为什么在第二个列表中,internalValue 与 value 不同,当 internalValue 被简单地分配为 this.value 时。有什么地方可以让我进一步阅读有关此主题的信息吗?
2021-04-04 16:42:29
@AlexAlexsondata组件中函数在组件的生命周期中仅运行一次该赋值是一个初始化值。value属性更改时,示例组件中没有任何内容会更新internalValue
2021-04-10 16:42:29
@Bert, AlexAlexson, 遵循Vue的内联补丁策略,对于第二个列表,由于应用状态和DOM之间没有正确的索引匹配,新的DOM元素会被添加到列表的末尾,并且会初始化internalValue =值(现在等于 5)。因此,您会看到它在列表末尾的 internalValue 始终为 5。更多信息可以参考:deepsource.io/blog/key-attribute-vue-js
2021-04-11 16:42:29

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>

为了更清楚