我正在尝试创建一个多文本输入组件。有一个父Vue组件来管理单个字段和一个组件用于单个输入。
父组件通过v-for渲染子组件,该组件绑定到对象数组。
data() {
return {
lastItemId: 0,
items: [{ id: this.lastItemId, value: '', showDeleteBtn: false}]
}
},
模板:
<div>
<input-item v-for='(item, index) in items'
:key="item.id"
:default-data="item"
@itemAdded="addItemAfter(index)"></input-item>
</div>
每当用户开始输入列表中的最后一个字段时,我发出的事件就是在其后面添加一个新的文本字段。
addItemAfter(index) {
if (index == this.items.length - 1) {
this.items.push({
id: ++this.lastItemId,
value: '',
showDeleteBtn: false
});
}
}
这很好用。但是,我还需要更新当前索引处的项目以显示该字段附近的删除按钮。无论我做什么,Vue都不会重新渲染该组件,除非我为该索引设置了一个具有不同ID的对象 - 这不是我想要的。
我尝试过的事情:
this.items[index].showDeleteBtn = true;
let item = this.items[index];
item.showDeleteBtn = true;
this.$set(this.items, index, item);
let item = this.items[index];
item.showDeleteBtn = true;
this.items.splice(index, 1, item);
this.$set(this.items[index], 'showDeleteBtn', true);
更新
这是子组件的这个问题部分中最重要的部分:
<button class="btn text-danger" v-show="showDeleteBtn" @click.prevent="removeItem">
<i class="glyphicon glyphicon-remove"></i>
</button>
// ....................................
props: ['defaultData'],
data() {
return {
itemId: this.defaultData.id,
item: this.defaultData.value,
showDeleteBtn: this.defaultData.showDeleteBtn
}
},
答案 0 :(得分:6)
更新项目时未显示删除按钮的原因是您的子组件的showDeleteBtn
属性值未更新。
该值未更新,因为data
方法中设置的Vue实例属性仅在初始化时设置一次。因此,showDeleteBtn
只能在data
方法中设置一次:
showDeleteBtn: this.defaultData.showDeleteBtn
当您更新被绑定为showDeleteBtn
道具的item
的{{1}}属性时,会更改子组件中defaultData
对象的值。但是,这不会自动更新子组件中的defaultData
属性。
最简单的解决方案是使showDeleteBtn
成为计算属性而不是showDeleteBtn
方法设置的属性:
data
这明确告诉Vue实例在computed: {
showDeleteBtn() {
return this.defaultData.showDeleteBtn;
}
}
值更新时更新showDeleteBtn
值。
另一个解决方案是让this.defaultData.showDeleteBtn
成为道具:
showDeleteBtn
并将props: { defaultData: Object, showDeleteBtn: Boolean },
的值绑定到父组件的那个prop:
item.showDeleteBtn
这样,对<input-item
v-for='(item, index) in items'
:key="item.id"
:default-data="item"
:show-delete-btn="item.showDeleteBtn"
@itemAdded="addItemAfter(index)"
/>
值的任何更改都将直接反映在子组件的item.showDeleteBtn
道具的值中。
这种方式也使得从父范围更清楚一点,如何更改showDeleteBtn
上的属性将影响子组件。