我有一个带有嵌套组件的相当复杂的对象。看起来像这样(将其向下拖动以便于阅读):
<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组件。
我怀疑这是由于重复的次要(外部)循环,但是我无法解决。
答案 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]);