美文网首页
2021-03-26 vue的provide和inject无法实

2021-03-26 vue的provide和inject无法实

作者: 追寻1989 | 来源:发表于2021-03-26 09:32 被阅读0次

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);
    },
},

相关文章