百科狗-知识改变命运!
--

依赖注入 - provide() 提供数据,inject() 接收数据 - vue 组件

乐乐1年前 (2023-11-21)阅读数 11#技术干货
文章标签组件

依赖注入

通常情况下,当我们需要从父组件向子组件传递数据时,会使用props。想象一下这样的结构:有一些多层级嵌套的组件,形成了一颗巨大的组件树,而某个深层的子组件需要一个较远的祖先组件中的部分内容。在这种情况下,如果仅使用props则必须将其沿着组件链逐级传递下去,这会非常麻烦:

这里的组件可能其实根本不关心这些props,但它仍然需要定义并将它们传递下去使得能访问到这些props,如果组件链路非常长,可能会影响到更多这条路上的组件。这一过程被称为“prop drilling”,这似乎不太好解决。

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


Provide(提供)

提供数据 Provide

要为组件后代提供数据,需要使用到provide()函数:

如果不使用

provide()函数接收两个参数:

  • 第一个参数,是注入名,可以是一个字符串或是一个Symbol。后代组件会注入名用来查找期望注入的值。一个组件可以多次调用provide(),使用不同的注入名,注入不同的依赖值。
  • 第二个参数,提供的值,可以是任意类型,包括响应式的状态。比如一个ref:
import { ref, provide } from 'vue'

const count = ref(0)
provide('key', count)

提供的响应式状态,使后代组件,可以由此和提供者,建立响应式的联系。


应用层 Provide

除了提供一个组件的数据,我们还可以在整个应用层面做提供:

import { createApp } from 'vue'
const app = createApp({})
app.provide('message', 'hello!')

应用级的提供在应用的所有组件中都可以注入。这在你编写插件时会特别有用,因为插件一般都不会使用组件形式来提供值。


Inject(注入)

要注入祖先组件提供的数据,需使用inject()函数:

如果提供的值是一个ref,注入进来的就是它本身,而不会自动解包。这使得被注入的组件保持了和提供者的响应性链接

同样的,如果没有使用

 {{ location }} 


最后,如果你想确保从provider传过来的数据不能被injector的组件更改,你可以使用readonly()来包装提供的值。


使用 Symbol 作注入名

依赖注入 - provide() 提供数据,inject() 接收数据 - vue 组件

至此,我们已经了解了如何使用字符串作为注入名。但如果你正在构建大型的应用程序,包含非常多的依赖提供,或者你正在编写提提供其他开发者使用的组件库,建议最好使用Symbol来作为注入名,以避免潜在的冲突。

建议在一个单独的文件中导出这些注入名 Symbol:

// keys.js
export const myInjectionKey = Symbol()
// 在提供方组件中
import { provide } from 'vue'
import { myInjectionKey } from './keys.js'

provide(myInjectionKey, { /* 要提供的数据 */ });
// 注入方组件
import { inject } from 'vue'
import { myInjectionKey } from './keys.js'

const injected = inject(myInjectionKey)

鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)