provide和inject是响应式的吗?

1,748 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第28天,点击查看活动详情

前情提要

provide和inject可能一些小伙伴用的并不是很多,毕竟进行组件间的通讯有N多种方式,而这种方式似乎并太招大家的待见。可能跟他的特性有关系吧。

provide和inject如何理解?

对于provide和inject如何理解这个问题可以这么来看:

  • 第一个是小程序的全局变量:globalData

    • WX20220627-234804@2x.png
    • 使用的时候直接获取使用即可:先const app = getApp();会获取globalData对象中所有的数据,然后就可以在Page中使用了。

    WX20220627-234849@2x.png

    • 这里面的概念跟provide和inject差不多。都是在顶级组件里定义,然后在后代组件中随意取用。
  • 第二个就是像是有人在你头上浇了一桶水,然后你从头部开始向下都会被水所侵湿。当然这个比喻并不是很恰当。但是表达的意思是一样的,在顶级组件中将事先准备好的数据通过provide进行注入,然后后代组件都可以通过inject直接取用。特点就是方向是由上而下。

那么provide和inject是响应式的吗?

响应式是Vue中最大的亮点之一,可以说没有响应式几乎就没有Vue的存在了,那么provide和inject也是Vue中提供的api,会是响应式的吗?下面我们就来试验一下吧:

  • 创建一个空项目,然后创建一个组件,并挂载到父组件里。这里用app.vue和helloworld.vue来做案例。 WX20220628-011824@2x.png WX20220628-011838@2x.png
  • 最后是运行结果 WX20220628-011922@2x.png
  • 由运行结果我们可以看到当我们改变基本数据类型的时候控制台会报错,虽然值也修改过来了,但是错误信息显示,当父组件重新渲染的时候该值还是会被再次覆盖,等同于没改。有风险,建议不要使用这种方式。
  • 根据结果中显示引用数据类型的数据被改变了,没有问题。

总结

从上面的结果来看,基本数据类型不可以被改变,也就是不是响应式的。但是引用数据类型可以被改变,那么对于引用数据类型而言它是响应式的吗?

  • 很显然不是。这跟js中的堆栈存储有关,并不是响应式的原因。
  • 所以最终的结果是provide/inject并不是响应式的。

留个小问题

那么如何实现provide和inject的响应式呢?