Vue依赖注入,详细解析

Prop 逐级透传问题​

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

Prop 逐级透传的过程图示

注意,虽然这里的 <Footer> 组件可能根本不关心这些 props,但为了使 <DeepChild> 能访问到它们,仍然需要定义并向下传递。如果组件链路非常长,可能会影响到更多这条路上的组件。这一问题被称为“prop 逐级透传”,显然是我们希望尽量避免的情况。

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

Provide/inject 模式

Provide (提供)​

要为组件后代提供数据,需要使用到 provide 选项:

export default {provide: {message: 'hello!'}
}

对于 provide 对象上的每一个属性,后代组件会用其 key 为注入名查找期望注入的值,属性的值就是要提供的数据。

如果我们需要提供依赖当前组件实例的状态 (比如那些由 data() 定义的数据属性),那么可以以函数形式使用 provide

export default {data() {return {message: 'hello!'}},provide() {// 使用函数的形式,可以访问到 `this`return {message: this.message}}
}

然而,请注意这不会使注入保持响应性。我们会在后续小节中讨论如何让注入转变为响应式。

应用层 Provide​

除了在一个组件中提供依赖,我们还可以在整个应用层面提供依赖:

import { createApp } from 'vue'const app = createApp({})app.provide(/* 注入名 */ 'message', /* 值 */ 'hello!')

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

Inject (注入)​

要注入上层组件提供的数据,需使用 inject 选项来声明:

export default {inject: ['message'],created() {console.log(this.message) // injected value}
}

注入会在组件自身的状态之前被解析,因此你可以在 data() 中访问到注入的属性:

export default {inject: ['message'],data() {return {// 基于注入值的初始数据fullMessage: this.message}}
}

注入别名​

当以数组形式使用 inject,注入的属性会以同名的 key 暴露到组件实例上。在上面的例子中,提供的属性名为 "message",注入后以 this.message 的形式暴露。访问的本地属性名和注入名是相同的。

如果我们想要用一个不同的本地属性名注入该属性,我们需要在 inject 选项的属性上使用对象的形式:

export default {inject: {/* 本地属性名 */ localMessage: {from: /* 注入来源名 */ 'message'}}
}

这里,组件本地化了原注入名 "message" 所提供的属性,并将其暴露为 this.localMessage

注入默认值​

默认情况下,inject 假设传入的注入名会被某个祖先链上的组件提供。如果该注入名的确没有任何组件提供,则会抛出一个运行时警告。

如果在注入一个值时不要求必须有提供者,那么我们应该声明一个默认值,和 props 类似:

export default {// 当声明注入的默认值时// 必须使用对象形式inject: {message: {from: 'message', // 当与原注入名同名时,这个属性是可选的default: 'default value'},user: {// 对于非基础类型数据,如果创建开销比较大,或是需要确保每个组件实例// 需要独立数据的,请使用工厂函数default: () => ({ name: 'John' })}}
}

和响应式数据配合使用​

为保证注入方和供给方之间的响应性链接,我们需要使用 computed() 函数提供一个计算属性:

import { computed } from 'vue'export default {data() {return {message: 'hello!'}},provide() {return {// 显式提供一个计算属性message: computed(() => this.message)}}
}

computed() 函数常用于组合式 API 风格的组件中,但它同样还可以用于补充选项式 API 风格的某些用例

使用 Symbol 作注入名​

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

我们通常推荐在一个单独的文件中导出这些注入名 Symbol:

// keys.js
export const myInjectionKey = Symbol()
// 在供给方组件中
import { myInjectionKey } from './keys.js'export default {provide() {return {[myInjectionKey]: {/* 要提供的数据 */}}}
}
// 注入方组件
import { myInjectionKey } from './keys.js'export default {inject: {injected: { from: myInjectionKey }}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/588801.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++心决之内联函数+auto关键字+指针空值

目录 7.内联函数 7.1 概念 7.2 特性 8. auto关键字(C11) 8.1 类型别名思考 8.2 auto简介 8.3 auto的使用细则 8.4 auto不能推导的场景 9. 基于范围的for循环(C11) 9.1 范围for的语法 9.2 范围for的使用条件 10. 指针空值nullptr(C11) 10.1 C98中的指针空值 7.内联…

水质监测站:守护水源,筑牢水质安全屏障

TH-LSZ06水质监测站&#xff0c;作为现代水质监测技术的创新成果&#xff0c;以其高效、便捷的特点&#xff0c;在水源保护、环境监测等领域发挥着越来越重要的作用。它不仅能够实时监测水质变化&#xff0c;提供准确的数据支持&#xff0c;还能为水质安全管理提供科学依据&…

深入理解Java内存模型及其作用

目录 1.前言 2.为什么要有 Java 内存模型&#xff1f; 2.1 一致性问题 2.2 重排序问题 3.Java 内存模型的定义 4.规范内容 4.1 主内存和工作内存交互规范 4.2 什么是 happens-before 原则&#xff1f; 1.前言 当问到 Java 内存模型的时候&#xff0c;一定要注意&#…

idea编译一直失败处理

切换分支的时候&#xff0c;明明代码正常&#xff0c;但是编译的时候一直失败。。。。特别是多个项目的时候&#xff0c;经常失败。 配置 -Djps.track.ap.dependenciesfalse idea默认是增量编译&#xff0c;设置这个false之后就从头开始编译了。 设置之后&#xff0c;点击编译&…

基于springboot的实习生管理系统

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

蓝桥杯每日不知道多少题之昂贵的聘礼

制作不易望点赞收藏加关注~~~&#xff0c;以便不时之需 题目连接&#xff1a;903. 昂贵的聘礼 - AcWing题库 解题思路&#xff1a;虚拟一个物品0&#xff0c;然后反向建边&#xff0c;边权为物品0到物品i所花费的价格&#xff0c;以及物品i换物品j所省下的钱&#xff0c;然后…

超机购ERP管理系统都有哪些功能模块?

在经济下行周期&#xff0c;众多手机店家正逐步向高效化和智能化迈进&#xff0c;手机行业作为数码产品的重要分支&#xff0c;正迎来前所未有的变革机遇。咱们超机购ERP系统&#xff0c;凭借对市场的敏锐洞察与技术创新&#xff0c;推出了超机系列工具&#xff0c;旨在引领手机…

docker容器技术篇:Docker API配置与常用操作

docker容器技术篇&#xff1a;Docker API配置与使用 一、API具体是什么&#xff1f; 百科解释应用程序接口&#xff08;API&#xff09;&#xff0c;又称为应用编程接口&#xff0c;就是软件系统不同组成部分衔接的约定&#xff0c;蒙了吧&#xff01;&#xff01;&#xff0…

杭州威雅学校:2024届90%毕业生获得世界排名前50大学录取

杭州威雅2024届90%毕业生 获世界排名前50大学录取&#xff01; 春光作序&#xff0c;万物和鸣。在四序岁始的春季&#xff0c;杭州威雅学校迎来了2024届毕业生如春雨般沁润人心的Offer&#xff01; 截至3月21日&#xff0c;杭州威雅学校2024届毕业生共收获54份offer&#xf…

一站式指南:Flutter应用如何顺利登陆苹果App Store

引言 &#x1f680; Flutter作为一种跨平台的移动应用程序开发框架&#xff0c;为开发者提供了便利&#xff0c;使他们能够通过单一的代码库构建出高性能、高保真度的应用程序&#xff0c;同时支持Android和iOS两个平台。然而&#xff0c;完成Flutter应用程序的开发只是第一步…

得物面试:10wqps高并发,如何防止重复下单?

尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格&#xff0c;遇到很多很重要的面试题&#xff1a; 10wqps高并发&#xff0c;如何防止重复提交/支付订单&…

RA8889/RA8876显示自定义汉字字符方法

本文介绍用户自己生成的汉字字库如何通过RA8889/RA8876显示到液晶屏上。 实例效果图&#xff1a; 汉字字库通过第三方软件生成&#xff0c;点阵是从右到右排列&#xff0c;左高位排法&#xff0c;网上有许多软件可用&#xff0c;这边就不再列举。 汉字表如下&#xff0c;可根…