javascript - 开发者工具中的 Vue 数组更新但不会重新渲染
问题描述
我有一个带有嵌套组件的相当复杂的对象。它看起来有点像这样(为了便于阅读而删除):
<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 方法运行时,它都会更新字段对象,但字段组件不会重新呈现。
我怀疑这是因为重复的次要(外部)循环,但我想不出办法。
解决方案
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]);
推荐阅读
- typescript - 如何删除 TS 中不相关的警告
- eclipse - 如何通过 Eclipse RSE 在远程服务器上自动上传本地项目文件更改?
- wordpress - Facebook分享在wordpress中抛出403禁止错误
- c - C 宏仅更改函数调用而不更改函数定义
- reactjs - 为什么不能渲染这个?
- c# - C# 无法从 DateTimePicker 将 Null 保存在数据库中
- swift - Why is sort(by:) unavailable in extensions to MutableCollection?
- c# - How to return an image as an IActionResult from an Image/Bitmap object
- javascript - 如何将时间字符串中的毫秒舍入为分钟?
- python - 如何使用并行 ssh 执行“su”命令