大家好, 我有些困惑。我有两个组件(子组件和父组件),并且将对象的属性作为道具传递
<child :child-data="abc" ></child>
Vue.component('childComponent', {
props: ['childData'],
data: function(){
return {
count:this.childData,// recommend use Vue.util.extend
}
},
});
Vue将把childComponent的“数据”属性递归转换为getter / setter,以使其“具有响应性”。 那么为什么不将数据自动绑定到模板呢?我读了一些建议使用Vue.util.extend。为什么选择Vue.util.extend?
更新
我的例子: https://jsfiddle.net/hoanghung1995/xncs5qpd/56/
当我设置parentData的默认值时,childDataA将显示它。但是,当我使用v模型来覆盖parentData时,childDataA不会“反应”。我必须使用“监视”来覆盖“数据”,类似于childDataB
Vue.util.extend示例:https://jsfiddle.net/sm4kx7p9/3/
为什么Vue.util.extend可以正常工作但不使用“监视”功能?,
答案 0 :(得分:1)
要说明后台实际发生的情况,请Linus Borg has as excellent answer for your question。总结一下他的答案,您的方法不起作用的原因是data
是一个计算属性,而props
被作为原始类型传递。换句话说,data
对您的道具进行复制(而不是通过引用传递)。
另一种绕过此方法的方法是将childData声明为计算属性而不是数据,即:
computed: {
childDataA() {
return this.childPropsA;
},
childDataB() {
return this.childPropsB;
}
}
使用computed
起作用的原因是因为现在计算出的属性可以监视对其依赖项的更改。
基于原始小提琴的概念验证示例:
Vue.component('child', {
props: ['childPropsA', 'childPropsB'],
template: "#sub",
computed: {
childDataA() {
return this.childPropsA;
},
childDataB() {
return this.childPropsB;
}
}
});
new Vue({
el: '#app',
data: {
parentData: '123'
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
parentData:{{parentData}}<br>
<input type="text" v-model="parentData">
<child :child-props-a="parentData" :child-props-b="parentData"></child>
</div>
<template id="sub">
<div>
<p> 1- {{ childDataA }}</p>
<p> 2- {{ childDataB }}</p>
</div>
</template>
以上方法在功能上与data
+ watch
方法相同,但是我觉得它很麻烦,并在您的代码中添加了不必要的冗长:
data: function() {
return {
childDataA: this.childPropsA,
childDataB: this.childPropsB
};
},
watch: {
childPropsA() {
this.childDataA = this.childPropsA;
},
childPropsB() {
this.childDataB = this.childPropsB;
}
}
Vue.component('child', {
props: ['childPropsA', 'childPropsB'],
template: "#sub",
data: function() {
return {
childDataA: this.childPropsA,
childDataB: this.childPropsB
};
},
watch: {
childPropsA() {
this.childDataA = this.childPropsA;
},
childPropsB() {
this.childDataB = this.childPropsB;
}
}
});
new Vue({
el: '#app',
data: {
parentData: '123'
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
parentData:{{parentData}}<br>
<input type="text" v-model="parentData">
<child :child-props-a="parentData" :child-props-b="parentData"></child>
</div>
<template id="sub">
<div>
<p> 1- {{ childDataA }}</p>
<p> 2- {{ childDataB }}</p>
</div>
</template>
答案 1 :(得分:0)
Watch仅监视确实具有反应性的属性。传递对象不会使它们的属性具有反应性。只需传递您想要作为道具的属性即可。 使用Vue.util.extend,您可以在这种情况下强制该属性为反应性的。