添加 :key 属性可以让vue识别DOM哪个是哪个
上图中,列表DOM每一项有复选框,勾选状态代表了DOM自身在列表中的位置。
现更新列表数据,以查看勾选项是否可以正确渲染。
先勾选第三项,再删除第三项。正确的DOM渲染应该是只留下了1 2 4项,且每一项都未勾选。
实际结果:
实际结果显示,如果没有正确的key属性(下方所示),勾选的项目会被认为是列表第三项,移除第三项后,第四项变成了第三项,所以导致错误地渲染了第四项的勾选状态。
同样,如果在列表前追加项目,也会导致同样的DOM渲染错误:
它仍然会认为第三项被勾选了。所以不管这个列表如何变化,都是固定的第三项保持勾选状态,这是不符合正常DOM结构的。
关键代码:
<div id="app">
<button @click="add">has key</button>
<button @click="remove1">has key remove</button>
<div v-for="(item,idx) in ds" :key="item.id">
<input type="checkbox">
<span>{{item.id}}::{{item.str}}</span>
</div>
<hr><hr><hr><hr>
<button @click="add2">no key</button>
<button @click="remove2">no key remove</button>
<div v-for="(item,idx) in ds2" ><input type="checkbox"> {{item.id}}::{{item.str}}</div>
</div>
var app = new Vue({
el: '#app',
data: {
ds: [{id:1,str:"s"},{id:2,str:"ss"},{id:3,str:"sss"},{id:4,str:"ssss"}],
ds2: [{id:1,str:"s"},{id:2,str:"ss"},{id:3,str:"sss"},{id:4,str:"ssss"}],
count1:5,
count2:5
},
methods:{
add(){
this.ds.unshift({id:this.count1,str:"lkjlj"})
this.count1++
},
add2(){
this.ds2.unshift({id:this.count2,str:"lkjlj"})
this.count2++
},
remove1(){
this.ds.splice(2,1)
},
remove2(){
this.ds2.splice(2,1)
}
}
})