前言
之前我们说过,通过props可以在父组件中向子组件传递数据。但是有些时候,子组件的下面还有子组件,组件会出现多层嵌套的情况,当最深层组件需要父组件的数据的时候,就会出现一个props逐级透传的情况,而组件也会形成一个一个巨大的组件树。
而在这个props的传递过程中,你会发现其中的有些组件可能并不需要这些props传递下来的数据,但是为了保证最深层的组件得到预期的数据,只能进行逐级透传。显然这种情况我们是不想看到的。
而为了解决这个问题vue也给提供了两个属性,来帮助我们解决这个问题 -- provide和inject。下面我们来具体看一看它把。
provide
通过provide()函数,我们可以使父组件对组件后代提供数据。也就是说,父组件可以作为一个依赖提供者,其后代的所有组件都可以通过注入的形式获取父组件提供的依赖。
<script setup> import { provide } from 'vue' provide(/* 注入名 */ 'title', /* 值 */ '我是标题!') </script> 复制代码
我们可以看到,provide接收两个参数,第一个参数是注入名,第二个参数是提供的值。而后代组件可以通过注入名来进行相应的数据注入。而且一个组件也可以进行多次调用provide进行注册。
当然,如果你想建立一个响应式的依赖,也可以通过ref来实现:
import { ref, provide } from 'vue' const title = ref('我是标题') provide('title', title) 复制代码
inject
通过inject()函数,可以注入其上级组件的数据。
<script setup> import { inject } from 'vue' const title = inject('title') </script> 复制代码
注意:如果提供的值是一个ref,为了保持其响应性,是不会进行自动解包的。
Symbol作为注入名
当我们在做一个数据业务复杂的大型项目时,可能会出现多个依赖,而我们就可以通过Symbol来作为注入名来避免命名冲突。
// injectKeys.js export const injectionTitle = Symbol() 复制代码
// 在供给方组件中 import { provide } from 'vue' import { injectionTitle } from './injectKeys.js' provide(injectionTitle, { /* 要提供的数据 */ }); 复制代码
// 注入方组件 import { inject } from 'vue' import { injectionTitle } from './injectKeys.js' const injectionTitle = inject(injectionTitle)