开发人员工具中的Vue阵列更新,但不会重新呈现

时间:2020-01-09 14:16:23

标签: javascript vue.js vuejs2 vue-component

我有一个带有嵌套组件的相当复杂的对象。看起来像这样(将其向下拖动以便于阅读):

<script type="text/x-template" id="fieldset-template">
    <div class="fieldset">
        <div class="fieldset-repetition" v-for="(repetition, key) in repetitions">
            <div class="field-list">
                <field v-for="field in fields" v-bind:key="field.key" v-bind:fieldset="field.fieldset" v-bind:fieldset-key="key" v-bind:field-data="field"></field>
            </div>
            <div class="repetition-meta">
                <a class="move-repetition" v-on:click="moveUp(key)">Up</a>
            </div>
        </div>
    </div>
</script>

<script type="text/x-template" id="field-template">
    <div class="field">
        <div class="form-group">
            <label class="control-label" v-html="name"></label>
            <div class="field-repetition" v-for="(repetition, key) in repetitions">
                <div class="field-text">
                    <input class="form-control" v-model="values[key]" />
                </div>
            </div>
        </div>
    </div>
</script>



<script>
    Vue.component('set', {
        components: {
            field: {
                created: function() {
                    // populate with data
                    this.populateData();
                },
                data: function() {
                    return {
                        repetitions: [],
                        values: [],
                    }
                },
                methods: {
                    populateData: function() {
                        this.repetitions = this.fieldData.repetitions;

                        this.repetitions.forEach(function(repetition, key) {
                            this.values = this.fieldData.value[this.fieldsetKey];
                        }.bind(this));
                    },
                    repeatField: function() {
                        var field = Object.clone(this);
                        delete field.repetitions;
                        this.repetitions.push(field);
                        if (this.widget != 'checkbox') {
                            this.values.push(this.fieldData.default);
                        }
                        else {
                            this.values.push([this.fieldData.default]);
                        }
                    },
                },
                props: {
                    fieldData: {
                        type: Object
                    },
                    fieldset: {
                        type: Object
                    },
                    fieldsetKey: {
                        type: Number
                    }
                },
                template: '#field-template'
            }
        },
        data: function() {
            return {
                fields: [FieldObject1, FieldObject2, FieldObject3],
                repetitions: [RepetitionObject1, RepetitionObject2,  RepetitionObject3,  RepetitionObject4,  RepetitionObject5],
            }
        },
        methods: {
            moveUp: function(key) {
                var field = this.fields[0];
                var value = field.value[key];
                field.value[key] = field.value[key - 1];
                field.value[key - 1] = value;
                this.$set(this.fields, 0, field);
            }
        },
        template: '#fieldset-template'
    });
</script>

无论何时运行moveUp方法,它都会更新fields对象,但不会重新渲染field组件。

我怀疑这是由于重复的次要(外部)循环,但是我无法解决。

1 个答案:

答案 0 :(得分:3)

this.$set(this.fields, 0, field);不会做任何事情,因为this.fields[0]已经等于field

假设field.value是一个数组,正是这一步做出了非反应性的更改:

field.value[key] = field.value[key - 1];
field.value[key - 1] = value;

请参见https://vuejs.org/v2/guide/list.html#Caveats

您可以将其编写为:

this.$set(field.value, key, field.value[key - 1]);
this.$set(field.value, key - 1, value);

或使用splice

field.value.splice(key - 1, 2, field.value[key], field.value[key - 1]);