嗨,大家好,
我有些困惑。我有两个组件(子组件和父组件),我将对象的属性作为道具传递
<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可以正常工作,但不使用“监视”?,
最佳答案
为解释后台实际发生的情况,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>