我们在v-for循环开发中需要给每一项去设置key,我们设置key的时候都习惯于用index去设置,比如
<ul>
<li v-for='(item,index) in list' :key='index'>
{{item.name}}
<button @click='deleteItem(index)></button>
</li>
</ul>
data(){
return{
list:[
{name:'小明'},
{name:'小王'},
{name:'小李'}
]
}
},
methods:{
deleteItem(){
this.list.splice(index,1)
}
}
我们项目中需要个删除功能,按照上面的配置我们能够准确的删除每一行,然而当我们项目越来越丰富的时候。比如:
<ul>
<li v-for='(item,index) in list' :key='index'>
{{item.name}}
<component-a @deleteItem='deleteItem(index)'></component-a>
</li>
</ul>
data(){
return{
list:[
{name:'小明'},
{name:'小王'},
{name:'小李'}
]
}
},
method:{
deleteItem(index){
this.list.splice(index,1)
}
}
Vue.component('component-a',{
data(){
provinces:[
{
area:"广东"
},
{
area:"湖南"
},
{
area:"江西"
}
]
},
methods:{
deleteItem(){
this.$emit('deleteItem',index)
},
}
template:'<select>
<option v-for='(item,index) in province' :key='index'>
</option>
</select>
<button @click='deleteItem(index)'></button>
'
})
当我们点击删除第一项的时候,下拉框的内容没有相对应的删除,反而删除的是最后一项。
按照个人理解,因为key值是是使用了index索引去设置,当数据重新渲染的时候,因为子组件的数据是没有被追踪到,为了高效操作dom,不引起页面的reflow回流,所以vue会复用当前的元素(我们列表中有0,1,2三项数据即索引index,我们删除第0项的时候,列表中经过重新渲染成0,1,因为key值不是唯一性,按照‘旧地复用’策略,我们的第三项数据即是最后一项的数据删除掉)。 因此,我们在设置key的时候,要给key值设置成唯一性
<ul>
<li v-for='(item,index) in list' :key='item.id'>
{{item.name}}
<component-a @deleteItem='deleteItem(index)'></component-a>
</li>
</ul>
data(){
return{
list:[
{name:'小明',id:0},
{name:'小王',id:1},
{name:'小李',id:2}
]
}
},
method:{
deleteItem(index){
this.list.splice(index,1)
}
} '
})
在数据列表添加id属性,给key值赋上唯一值。这样我们就可以进行正常的删除。