vue中的provide可以进行父组件向后代组件进行传值。但是,他没办法监听传输数据的变化。或者说明白点,就是如果我在父组件改变注入的值,它没办法更新。子组件改变传入的值,它也没办法进行更新
vue官方说明:https://cn.vuejs.org/v2/api/#provide-inject
在线测试地址:https://codesandbox.io/s/snowy-forest-zed14
我们经过测试发现:
// 父组件
provide: function() {
this.myData3 = Vue.observable({
val: "我没改变",
});
return {
myData1: this.myData1, //非响应
myData2: this.myData2, //响应
myData3: this.myData3, //响应
};
},
data() {
return {
myData1: "我没改变",
myData2: {
val: "我没改变",
},
};
},
methods: {
change(){
this.myData1 = "我改变了" // 触发后不能改变
this.myData2.val = "我改变了" // 触发后能改变
this.myData3.val = "我改变了" // 触发后能改变
// 触发后不能改变
this.myData2 = {
val: "我改变了",
}
// 触发后不能改变
this.myData3 = {
val: "我改变了",
}
},
}
// 孙组件
inject: ["myData1", "myData2", "myData3"],
以上这几种方式都无法响应和对一整个对象赋值的改变,并且watch和computed也无法监听到一整个对象赋值的改变,只能响应和监听某个对象中的属性改变,这不符合我们的使用习惯,我们希望可以对一整个对象赋值并监听它的改变
如果我们希望整个数据都是响应式的。那么可以通过以下方法实现:
我们可以让provide提供一个函数。函数内部返回一个响应式的数据。此时整条数据的响应式的状态并不会丢失。
而且这样做有一个好处,即无法直接修改myData4 的值,因为他是一个计算属性。这样就可以避免数据的混乱。
关键代码如下:
// 父组件
provide: function () {
return {
myData4: () => this.myData4, //响应
};
},
data() {
return {
myData4: {
val: "我没改变",
},
};
},
methods: {
change() {
// 触发后能改变
this.myData4 = {
val: "我改变了",
};
},
},
// 孙组件
inject: ["myData4"],
computed: {
computedMyData4() {
return this.myData4()
}
},
watch: {
computedMyData4(val) {
console.log("我是孙组件,我监听到了myData4改变", val);
},
},
网友评论