我在几个项目中使用过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>
llycmphe1#
因为数组是可变的。如果在数组中添加或删除项,则任何给定项的索引都可以并将 * 改变 *。您希望您的key是一个唯一的值,它只标识您的唯一组件。创建主键总是比使用索引更好。这里有一个例子。
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 * 所在的数组中的新数字;在按钮下面的第二个列表中,值不代表数组中的实际位置,内部值和属性值不一致。
addValue
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将按如下方式跟踪每个项目:
B
A: 0 C: 1 D: 2
C和D的索引已经改变,所以Vue失去了对它们的跟踪,并且将从渲染输出中移除D而不是B(因为从它的Angular 来看,移除的是索引为3的项)。这就是为什么键应该唯一地标识一个项,而索引不能做到这一点。但是,这也意味着在某些情况下使用索引作为键是可以接受的:
C
D
如果您不能使用索引作为键,但又不能唯一标识项目(例如,列表中的某些项目是相同的),则可以使用lodash的uniqueId():
uniqueId()
<div v-for="item in data" :key="uniqueId()">
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>
为了更清楚
3条答案
按热度按时间llycmphe1#
因为数组是可变的。如果在数组中添加或删除项,则任何给定项的索引都可以并将 * 改变 *。
您希望您的
key
是一个唯一的值,它只标识您的唯一组件。创建主键总是比使用索引更好。这里有一个例子。
注意,当单击
addValue
时,顶部的列表表示数组中 * trully * 所在的数组中的新数字;在按钮下面的第二个列表中,值不代表数组中的实际位置,内部值和属性值不一致。qcbq4gxm2#
来自Vue文档(强调我的):www.example.comhttps://vuejs.org/guide/essentials/list.html#maintaining-state-with-key
要给Vue一个提示,以便它可以跟踪每个节点的标识,从而重用和重新排序现有元素,您需要为每个项提供一个unique key属性
如果数组中任何项目的索引发生变化(例如,通过在数组末尾以外的任何位置添加/删除新项目),则Vue将失去对该项目的跟踪。
例如:
Vue按如下方式跟踪每个项目:
如果您从数组中删除
B
,Vue将按如下方式跟踪每个项目:C
和D
的索引已经改变,所以Vue失去了对它们的跟踪,并且将从渲染输出中移除D
而不是B
(因为从它的Angular 来看,移除的是索引为3的项)。这就是为什么键应该唯一地标识一个项,而索引不能做到这一点。
但是,这也意味着在某些情况下使用索引作为键是可以接受的:
如果您不能使用索引作为键,但又不能唯一标识项目(例如,列表中的某些项目是相同的),则可以使用lodash的
uniqueId()
:izkcnapc3#
为了更清楚