【发布时间】:2019-01-16 12:38:00
【问题描述】:
我有两个组件,如下所示:
Vue.component('comp-child', {
template: `<div>{{childData.name}}<slot></slot>{{randomNum}}</div>`,
props: {
parentData: {
}
},
data() {
return {
childData: {},
randomNum: Math.round(Math.random() * 100)
};
},
created() {
this.childData.name = this.parentData.name;
}
});
Vue.component('comp-parent', {
template: `<div><component v-for="(item, index) in arr" is="comp-child" :key="index" :parent-data="item">
<button @click="deleteItem(index)">delete</button>
</component>
</div>`,
data(){
return {
arr: [{
name:1
}, {
name:2
}, {
name:3
}, {
name:4
}, {
name:5
}]
};
},
methods: {
deleteItem(index) {
this.arr.splice(index, 1);
console.log(`${index}th element deleted! `);
}
}
});
let app = new Vue({
el: '#app'
});
<script src="https://unpkg.com/vue"></script>
<div id="app">
<comp-parent></comp-parent>
</div>
在这个demo中,无论你点击哪个item,最后一个item都会被删除。
我定位到这个问题是v-for的key引起的,如果使用1, 2, 3, 4,..作为key,会出现这个问题,但是使用其他值作为key,比如string,它就可以正常工作;
template: `<div><component v-for="(item, index) in arr" is="comp-child" :key="item.key" :parent-data="item">
<button @click="deleteItem(index)">delete</button>
</component>
</div>`,
data(){
return {
arr: [{
name:1,
key: 'key1'
}, {
name:2,
key: 'key2'
}, {
name:3,
key: 'key3'
}, {
name:4,
key: 'key4'
}, {
name:5,
key: 'key5'
}]
};
},
检查这个小提琴:demo
是不是虚拟DOM造成的?似乎 VUE 将 key 和子组件绑定为缓存,当 arr 更改时,它只是按照 index(1,2,3,..) 的顺序重新渲染组件,如果 arr 中的某些项目被删除,则arr 的长度减少导致最后一个无法渲染。
请有人给我解释一下,谢谢!
【问题讨论】:
-
您应该传递密钥以从数组中删除一个项目。因为 Vue 文档建议不要使用索引作为键
-
@latovic,如果密钥是 1,2,3……,通过密钥删除项目仍然会导致这个问题,不是吗?所以我想知道为什么使用索引删除不起作用
标签: caching vue.js vue-component v-for virtual-dom