更新资料
Vue JS 3将正确处理此问题:https://blog.cloudboost.io/reactivity-in-vue-js-2-vs-vue-js-3-dcdd0728dcdf
问题:
我有一个Vue组件,看起来像这样:
子公司
<template>
<div>
<input type="text" class="form-control" v-model="textA">
<input type="text" class="form-control" v-model="textB">
<input type="text" class="form-control" v-model="textC">
</div>
</template>
<script>
export default {
props: {
textA: {
type: Number,
required: false
},
textB: {
type: Number,
required: false
},
textC: {
type: Number,
required: false
}
}
}
</script>
我有一个看起来像这样的父组件:
布局比较
<template>
<div>
<button @click="addItem">Add</button>
<ul>
<li v-for="listItem in listItems"
:key="listItem.id">
<sub-comp
:textA="listItem.item.textA"
:textB="listItem.item.textB"
:textC="listItem.item.textC"
/>
</li>
</ul>
</div>
</template>
import subComp from '../sub-comp.vue'
export default {
components: {
subComp
},
data() {
return {
listItems: []
}
},
methods: {
addItem: function () {
var item = {
textA: 5,
textB: 100,
textC: 200
}
if (!item) {
return
}
this.length += 1;
this.listItems.push({
id: length++,
item: item
});
}
}
</script>
关键是,我所做的任何编辑文本框的操作,即使反应性数据表明它已更改,数组也不会更改。例如,它将始终是
{
textA: 5,
textB: 100,
textC: 200
}
即使我更改了textB:333,listItems数组仍然显示textB:100。这是由于以下原因:
https://vuejs.org/v2/guide/list.html#Caveats
由于JavaScript的限制,Vue无法检测到对数组的以下更改
题:
我想知道如何更新阵列?我还希望使用@blur事件在离开文本框时进行更改。我想看看可以怎么做。
我读了这些材料:
https://codingexplained.com/coding/front-end/vue-js/array-change-detection
https://vuejs.org/v2/guide/list.html
但是似乎我的示例有点复杂,因为它具有关联的索引,并且数组具有复杂的对象。
更新4/12/2018
发现我的addItem()中有:
item = this.conditionItems[this.conditionItems.length - 1].item);
至
item = JSON.parse(JSON.stringify(this.conditionItems[this.conditionItems.length - 1].item));
我认为以下答案中的sync修饰符会引起问题,因为它重复了所有项目。但是事实并非如此。我正在复制一个vue对象(包括可观察的属性),导致它发生。 JSON分析和JSON字符串化方法仅将属性复制为普通对象,而没有可观察的属性。这里讨论过:
https://github.com/vuejs/Discussion/issues/292
最佳答案
问题是道具从父母到孩子在一个方向上流动。
在子级中使用v-model设置值不会影响父级的数据。
Vue有一个快捷方式,可以更轻松地更新父母的数据。它称为.sync modifier。
就是这样。
在子补偿中
<template>
<div>
<input type="text" class="form-control" :value="textA" @input="$emit('update:textA', $event.target.value)" >
<input type="text" class="form-control" :value="textB" @input="$emit('update:textB', $event.target.value)">
<input type="text" class="form-control" :value="textC" @input="$emit('update:textC', $event.target.value)">
</div>
</template>
<script>
export default {
// remains the same
}
</script>
添加道具时添加.sync
<sub-comp
:textA.sync="listItem.item.textA" // this will have the same effect of v-on:update:textA="listItem.item.textA = $event"
:textB.sync="listItem.item.textB"
:textC.sync="listItem.item.textC"
/>
更新:
如果您有反应性问题,请不要使用.sync,添加自定义事件并使用$ set
<sub-comp
:textA="listItem.item.textA" v-on:update:textA="$set('listItem.item','textA', $event)"
/>
关于javascript - Vue JS 2中对复杂对象数组的数组更改检测,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49765758/