【发布时间】:2018-08-03 16:13:04
【问题描述】:
访问子组件的计算属性的正确方法是什么?下面是我正在尝试实现的简化示例(也可在 JSFiddle 上找到):
const FoobarWidget = {
template: '<li>a: <input type="text" v-model="value.a" style="width:2em;"> b: <input type="text" v-model="value.b" style="width:2em;"> sum: {{this.sum}} <button @click="die">x</button></li>',
props: {
value: {
type: Object,
required: true,
}
},
computed: {
sum() {
const s = Number(this.value.a) + Number(this.value.b)
// WARNING eslint - vue:no-side-effects-in-computed-properties
this.value.sum = s;
return s;
}
},
methods: {
die() {
this.$emit('die');
}
}
};
new Vue({
el: '#app',
data: {
foobars: [{
a: '5',
b: '6'
}],
},
components: {
FoobarWidget,
},
computed: {
myJson() {
return JSON.stringify(this.foobars, null, 2);
}
},
methods: {
addNew() {
this.foobars.push({
a: '1',
b: '2'
});
},
foobarDead(index) {
this.foobars.splice(index, 1);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<div id="app">
<button @click="addNew()">add foobar</button>
<h3>Foobars</h3>
<ul>
<foobar-widget v-for="(foobar, index) in foobars" :key="index" @die="foobarDead(index)" v-model="foobars[index]"/>
</ul>
<h3>JSON</h3>
<pre>{{myJson}}</pre>
</div>
正如您在尝试此示例后所看到的那样,它大部分都有效 - 除了在更改子组件(a、b 和计算总和)中的值之后,它不能很好地反映父组件(生成的 JSON)中的更改。
这个问题似乎类似于SO: Computed property on child component props,但是该问题的 OP 有一个计算值来进行字符串格式化,因此使用 Vue 过滤器是一个很好的解决方案。这不是这里的情况 - sum() 计算属性可以是任意函数,需要在父组件和子组件中访问。
我在上面做的方式,通过在重新计算时添加sum 属性来修改 prop 对象绝对不是正确的方法,因此我的问题。它不仅可以正常工作,而且还会产生 ESLint 警告(上面代码中的 WARNING 注释)。
【问题讨论】:
标签: javascript vue.js vuejs2 vue-component