众所周知,vue3中加入了依赖注入的方法,我也一直都在用。一次声明所有后代组件都可用,直接声明在根上全局可用,简直不要太爽!今天后端说他们java也有依赖注入,我发现我只会用却不知道原理,今天就好好看看vue3依赖注入的原理和好处坏处。
- 在vue2中通常情况下,我们需要从父组件向子组件传递数据时,会使用 props。如果我们有一些多层级嵌套的组件,形成了一个巨大的组件树,而某个深层的子组件需要一个较远的爷爷的爷爷组件中的部分数据。在这种情况下,如果仅使用 props 则必须将其沿着组件链逐级传递下去,这会非常麻烦:
虽然这里的 <Footer> 组件根本不需要这些 props,但为了让 <DeepChild> 组件能拿到props的数据,它仍然需要定义props并且向下面的组件传。如果组件链路非常长,可能会影响到更多这条链子上的组件。这个问题被称为“prop 逐级透传”,多了很多无意义的代码,并且非常难以维护。
这个时候就需要依赖注入闪亮登场了,provide 和 inject 一个父组件相对于其所有的后代组件,会作为依赖提供者。任何后代的组件树,无论层级有多深,都可以由父组件提供给整条链路的依赖。一次注入,受用终身。
依赖注入的使用
注入
provide() 函数接收两个参数。第一个参数被称为注入名,可以是一个字符串或是一个 Symbol。后代组件会用注入名来查找期望注入的值。一个组件可以多次调用 provide(),使用不同的注入名,注入不同的依赖值。
第二个参数是提供的值,值可以是任意类型,包括响应式的状态
import { createApp } from 'vue'
const app = createApp({})
app.provide(/* 注入名 */ 'message', /* 值 */ 'hello!')
在需要使用的组件中引入使用
<script setup> import { inject } from 'vue'
const message = inject('message') </script>
五行代码就可以搞定长链路传值问题,隔了很多代的传值强烈推荐这个方法传值,挂载在app.vue上全局可用。
Provide 和 Inject 的注意事项
- Provide 和 Inject 只能在父子组件之间使用。对于兄弟组件之间的数据共享,建议使用 Vuex 等状态管理工具。
- Provide 和 Inject 注入的数据是响应式的。如果提供的数据发生变化,那么所有注入了该数据的组件都会相应地更新。
- Provide 和 Inject 不保证注入顺序。如果多个组件都提供了同一个键名,注入的顺序不确定,可能会导致组件的渲染结果出现意外情况。
- Provide 和 Inject 不限制嵌套层数。在组件树中,Provide 和 Inject 可以一直循环注入,直到找到对应的数据或方法。