我正在尝试创建一个有两个插槽的组件。第二个插槽基于第一个插槽中的项目数重复。我使用作用域插槽实现了这一点,但是,当在第一个插槽上更新数据时,第二个插槽在触发事件之前不会自动更新它,例如:单击调用方法的按钮。
当在第一个插槽上更改数据时,有没有办法让第二个插槽更新其视图?
以下是我的例子:
Jsfiddle:https://jsfiddle.net/89vykm75/1/
new Vue({
el: '#app',
components: {
'repeat-for-each-item': {
data: function() {
return {
items: []
}
},
template: `<div>
<slot name="item" v-for="item in items" :item="item"></slot>
<button @click="addItem()">Add item</button>
<slot name="repeat" v-for="item in items" :item="item"></slot>
</div>
`,
methods: {
addItem() {
this.items.push({});
}
}
}
}
});
<div id="app">
<repeat-for-each-item>
<template slot="item" scope="props">
<div>
<input type="text" v-model="props.item.name">
</div>
</template>
<template slot="repeat" scope="props">
<div>
<label>
<span v-if="props.item.name">{{props.item.name}}:</span>
<span v-else>No Name:</span>
</label>
<input type="text">
</div>
</template>
</repeat-for-each-item>
</div>
答案 0 :(得分:2)
我通过调用keyup上的方法找到了解决方案。
基本上,我在插槽
上添加了@keyup事件<input type="text" v-model="props.item.name" @keyup="props.onchange()">
在组件模板上,将onchange方法传递给插槽
<slot name="item" v-for="item in items" :item="item" :onchange="onchange"></slot>
然后使用onchange函数强制重新渲染
onchange:() => {
// hack to trigger changes
this.$set(this.items, 0, this.items[0]);
}
以下是完整工作的JsFiddle:https://jsfiddle.net/89vykm75/2/
我想知道是否有更清洁的解决方案?
答案 1 :(得分:2)
你正陷入Vue change detection caveat。这里的问题是,如果在将对象添加到Vue数据之前向对象添加属性,则Vue无法检测到更改。这是问题所在:
this.items.push({})
您正在添加没有属性的对象,然后将v-model
绑定到该对象的name
属性,该属性不存在。 Vue无法检测到更改,也不会更新绑定到该属性的其他项。
如果您改为这样做:
this.items.push({name: null})
您会发现您的代码有效。这是更新后的fiddle。