问题是由
v-for的就地补丁策略
。这意味着当从componentList中删除一个元素时,Vue不会重建所有子级。
检查
Vue Guide on an âin-place patchâ strategy for v-for
:
当Vue更新使用v-for渲染的元素列表时,通过
默认情况下,它使用就地修补策略。如果数据的顺序
项已更改,而不是移动DOM元素以匹配
项目顺序,Vue将修补每个元素并确保
它反映了在该特定索引处应该呈现的内容。
实际上,您已经删除了最后一项,但问题是数据属性=currentValue of first&第一次安装时,第二个孩子是“a”、“b”。稍后,当Vue重新渲染(删除最后一个子级)时,data property=currentValue保持相同的值,尽管prop=myVal已更改。
看看下面的演示,我添加了一个输入并绑定了myVal,您将看到不同之处。
Vue.config.productionTip = false
let childComponent = Vue.component('child', {
template: `<div class="item">
<p>Index:{{parentIndex}} => <button @click.prevent="removed()" > Remove </button>
Data:<input type="text" v-model="currentValue" />Props:<input type="text" v-bind:value="myVal" />
</p>
</div>`,
props: { 'myVal':{
type: String,
default: ''
} ,
'parentIndex': {
type: Number,
default: 0
}
},
data() {
return {
currentValue: ''
}
},
mounted() {
this.currentValue = this.myVal
},
methods: {
removed: function () {
this.$emit('remove')
}
}
})
app = new Vue({
el: "#app",
data() {
return {
componentList: ['a', 'b', 'c'],
componentType:childComponent
}
},
methods: {
addField() {
console.log('Handling add-custom-field field...');
this.componentList.push(childComponent);
},
dropField(index) {
console.log(`I am deleting the component with index = ${index} from listview in parent...`);
this.componentList.splice(index, 1);
}
}
})
li:nth-child(odd) {
background-color:#d0d5dd;
}
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<div id="app">
<ul>
<li v-for="(child, index) in componentList"><div
:is="componentType"
:key="index"
:my-val="child"
:parent-index="index"
@remove="dropField(index)"
@add-custom-field="addField"
>{{child}}</div></li>
</ul>
</div>