更新资料

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/

10-11 22:22
查看更多