inject/provide与响应式数据

Vue的inject/provide响应性解析
Vue的provide/inject绑定不具备默认的响应性。仅当提供的是可监听对象时,其属性才保持响应。这意味着当父组件的provide数据变化时,子组件的inject不会更新,但若提供的是一个对象,其属性的变动则可被检测到。文章通过代码示例详细阐述了这种情况,并指出尽管inject/provide类似props传递,但它们在响应式处理上存在差异,无法直接用于计算属性。

provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。

说人话就是如果你把对象都改了那这个改动就追踪不到了,如果你就改了个对象属性那这种响应就能追踪到。以下是具体的代码分析。

这意味着,出于某种考虑,vue故意将provide/inject设定为不可响应的。也就是说如果你的provide的数据改变,inject是不会接受到这个改变,然而如果你provide的内容是一个可响应的数据,比如一个对象引用,那么这个对象的属性是可以检测到变化的。举例来说:

provide(){
  return{
    foo:this.msg
  }
},
data() {
  return {
    msg: "hello",
  }
}
mounted(){
  setTimeout(()=>{
    this.msg = "world";
  },3000)
}

而此时你在子组件中去监测:

inject:{
    foo: { default: {} }
}

就会发现不管父组件的foo怎么更改,子组件的foo都不会改变。
而如果你改变的不是对象,而是对象的属性,那么这个改变就可以被监测,举例来说:

provide(){
  return{
    foo: this.msg
  }
},
data() {
  return {
    msg: {
        bar: 'hello'
    }
  }
}
mounted(){
  setTimeout(()=>{
    this.msg.bar = "world";
  },3000)
}

那么此时子组件就可以监听到属性的变动。
这里有一个重点,这个属性更改是以引用不变前提下的属性更改,如果引用变动了,那就是对象改变而不是对象的属性改变了。举个例子:

mounted(){
  setTimeout(()=>{
      // 这种情况下叫改变了属性,属性的更改是可以响应的
    this.msg.bar = "world";
    // 这种情况就是对对象的重新赋值,也就是把对象引用都改了,这种是不可响应的
    this.msg = {
        bar: 'world'
    }
  },3000)
}

看到了响应式的问题已经解决了,inject也确实会随着provide的属性变更而改变数据。
但是怀着打破砂锅问到底的方针,这种改变是否可以被本地监测呢?像这样data和computed数据是可响应的吗?如下:

data() {
    return {
      data: this.boardData.data
    };
  },
  inject: {
    boardData: { default: {} }
  },
  computed: {
    data1() {
      return this.boardData.data;
    }
  }

经过严谨的实验,答案是不能,因此尽管号称inject/provide是类似于props这种父子组件传值的,祖孙组件传值,但是实现方式并不相同。
结果如下:

因此需要用的inject的计算值的时候还是直接算,不要指望能用computed取返回响应的计算值了

评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值