前言陈述

Vue的一个主要理念就是组件化。然而,在复杂的应用中,组件之间的通信可能变得很复杂。为了解决这个问题,Vue3提供了一种叫做provide和inject的机制,使得我们可以在父级组件中提供变量,在子孙级组件中注入和使用它们。在Vue 3中,provide和inject的使用更加便捷和高效。本文就来和大家一起深入浅出,共同探讨一下这两个API。

组件通信对比

为了让开发者快速了解provide和inject两个API的功能,vue作者尤雨溪做了两张有趣的对比图,主要针对的就是复杂组件传参问题。

先看看传统的传参props方式,在复杂页面通信流程图:

从这张图不难看出,复杂组件用props是属于逐级传递了,中间环节只要报错,参数就消失不见了。而且每个组件都需要写一遍,接受props和绑定,非常繁琐。注意,虽然这里的 <Footer> 组件可能根本不关心这些 props,但为了使 <DeepChild> 能访问到它们,仍然需要定义并向下传递。如果组件链路非常长,可能会影响到更多这条路上的组件。这一问题被称为“prop 逐级透传”,显然是我们希望尽量避免的情况。既然遇到了这样的问题,那么解决方案就浮出水面了。

provide 和 inject 可以帮助我们解决这一问题 。一个父组件相对于其所有的后代组件,会作为依赖提供者。任何后代的组件树,无论层级有多深,都可以注入由父组件提供给整条链路的依赖。

怎么理解?请看下图:

Provide和Inject到底是什么?

在Vue中,provide和inject机制允许父级组件定义,并为其所有的子孙级组件提供变量。在任何子孙级组件中,你可以通过inject这个变量并使用它。这种跨级别的组件通信方式特别适用于那些复杂的嵌套组件结构,避免繁琐的中间传递。

就像这张图,父组件包含许多子组件,采用provide和inject实现组件之间的通信逻辑就是这样:

如何使用Provide和Inject?

这里使用vite5+vue3的setup语法糖,当前vue版本:3.4.27。provide和inject是和ref api 一样的,如果没有全局注入vue接口,那么就到import导入才能使用。

案例代码已全局注入vue接口,不需要导入,在父组件中结尾处提供变量即可,写法如下:

注意当这样写之后,当变量变化后,子组件也能及时获得,简直太爽了。

子组件要使用的话,需要写一个hooks,或者直接导入也行,这里采用前者。

写一个hooks方法,用于获取父组件提供的变量

子组件使用这样变量,就可以这样导入使用。

父组件HTML结构就是这样的,将会注入很多子组件,当使用provide和inject方案通信后,就不需要 :xxx=‘xxx’了。

特别提醒

虽然provideinject为我们提供了方便,但我们需要谨慎使用,以避免以下几个问题:

注入未提供的属性: 如果你试图注入一个尚未被任何父级组件提供的变量,Vue会返回undefined。为了避免这个问题,最好总是提供一个默认值。

变量名冲突: 当多个父级组件提供了相同名字的变量时,子孙级组件将注入最近的那个。为了避免冲突,建议使用具有唯一性的名称

总结

总结来说,Vue 3的provide和injectAPI提供了一种强大且灵活的方式来处理复杂的组件通信问题。不过,记住任何工具都有其使用场景,无论何时应该深思熟虑并制定适合项目的最佳实践