【Vue.js 3.0】provide 、inject 函数详解

embedded/2024/12/22 8:01:20/
  1. 在 Vue 3 中,provideinject 是用于跨组件层次结构进行依赖注入的一对 API。
  2. 这些 API 主要用于祖先组件和后代组件之间的数据传递,尤其是当这些组件之间没有直接的父子关系时。

1. 示例

1.1 provide

provide 函数用于在祖先组件中定义一个值,使得其所有后代组件都可以使用 inject 来访问这个值。

用法

provide(key, value)
  • key:一个字符串或 Symbol,用于唯一标识所提供的值。
  • value:所提供的值,可以是任何类型。

1.2 inject

inject 函数用于在后代组件中访问祖先组件通过 provide 所提供的值。

用法

const value = inject(key, defaultValue)
  • key:与 provide 相同的字符串或 Symbol。
  • defaultValue:一个可选的默认值,当 provide 没有提供该 key 对应的值时,inject 将返回这个默认值。

假设我们有一个祖先组件 GrandParent,一个中间组件 Parent,以及一个后代组件 Child。我们希望从 GrandParent 传递一个数据到 Child

GrandParent.vue
<template><Parent />
</template><script setup>
import { provide } from 'vue';
import Parent from './Parent.vue';const theme = 'dark';
provide('theme', theme);
</script>
Parent.vue
<template><Child />
</template><script setup>
import Child from './Child.vue';
</script>
Child.vue
<template><div :class="theme">I am a child component with {{ theme }} theme.</div>
</template><script setup>
import { inject } from 'vue';const theme = inject('theme', 'light'); // 'light' 是默认值,如果 provide 没有提供 'theme'
</script><style scoped>
.dark {background-color: black;color: white;
}.light {background-color: white;color: black;
}
</style>

2. 实现原理

2.1 Vue.js 2.0

  • 在 Vue.js 2.0 中组件实例方法和属性的继承是通过原型链来实现的,而 provide 和 inject 就是基于原型链的属性访问来实现跨组件通信。
  • 当一个组件通过 provide 提供数据,它会将这些数据添加到其原型链上,然后子组件通过 inject 可以在原型链上查找并访问这些数据。

2.2 Vue.js 3.0

  • 在 Vue 3 中 组件的实例方法和属性的继承不再依赖于原型链,而是 引入了 Composition API,它采用了一种不同的方式来组织组件的代码和状态。
  • 组件的选项被重构为一个配置对象,其中 setup 函数用于定义组件的响应式数据、计算属性、方法等。
  • 这些选项不再依赖于原型链,而是直接导出给组件实例。

2.3 改进带来了以下好处

  • 更稳定的数据提供:在 Vue 3 中,每个组件实例都有自己的私有作用域,不会受到原型链的影响,因此不存在 Vue 2 中的潜在问题。
  • 更好的类型检查:在 Vue 3 中,TypeScript 或 Flow 等类型检查工具可以更准确地检测到 inject 注入的数据类型。

详解

2.2.1 provide 的原理

  • provide 在父组件中使用的选项,用于提供数据给子组件。它实际上是一个函数,它会在父组件实例上创建一个名为 _provided 的对象。
  • _provided 对象存储了提供给子组件的数据,而且这些数据会在整个组件树中可用,子组件可以通过 inject 选项来访问这些数据。
  • 当父组件提供的数据发生变化时,Vue 3 的响应式系统会追踪这些变化并通知所有依赖这些数据的子组件进行更新。

2.2.2 inject 的原理

  • 子组件通过 inject 选项声明需要注入的数据,可以是一个数组、一个对象或一个函数。这些声明告诉 Vue 3 要从父组件的提供数据中获取哪些属性。
  • 当子组件访问通过 inject 注入的数据时,Vue 3会在组件树中向上搜索父组件,直到找到包含提供数据的组件或到达根组件。
  • 一旦找到包含提供数据的组件,Vue 3 会从该组件的 _provided 属性中获取相应的数据。
  • 如果提供的数据是响应式的,子组件将自动成为这些数据的依赖,当提供的数据发生变化时,子组件将被通知并进行更新。

优点:

  • 解耦合(Decoupling): provide 和 inject 有助于降低组件之间的耦合度。组件不需要直接了解其依赖项的实现细节,而是通过注入来访问这些依赖,这使得组件更加独立和可复用。
  • 可测试性(Testability): 依赖注入使得单元测试更加容易。你可以轻松地注入模拟对象或测试替身,以测试组件的行为,而不需要实际的外部依赖。
  • 可维护性(Maintainability): 通过将依赖项提取到外部并通过 provide 注入,代码变得更清晰和易于维护。这对于大型应用程序来说特别有价值。
  • 可扩展性(Scalability): provide 和 inject 可以用于共享全局配置、服务或状态管理等全局性的依赖项,使得应用程序更容易扩展和维护。

缺点:

  • 复杂性(Complexity): 对于小型应用来说,使用 provide 和 inject 可能会增加一些不必要的复杂性。这些特性最有价值的地方通常在大型和复杂的应用程序中。
  • 容易滥用(Overuse): 有时开发人员可能会滥用 provide 和 inject,将所有东西都注入到组件中,导致不必要的复杂性和混乱。需要谨慎权衡。
  • 不适用于所有场景(Not Suitable for All Scenarios): provide 和 inject 更适合用于共享全局配置和服务等情况,对于局部的、仅在某个组件内部使用的依赖项,使用 props 更合适。

3.注意事项

  • 响应性:通过 provide 提供的值不会自动具有响应性。如果需要响应性,应该提供一个响应式对象或使用
    reactiveref 等 Vue 的响应式 API。
  • 循环依赖:虽然 provide 和 inject 强大,但应谨慎使用,以避免组件间的循环依赖。
  • 作用范围:provide 和 inject 的作用范围仅限于当前的组件树,无法跨组件树使用。通过使用 provideinject,开发者可以在 Vue 3 应用中灵活地管理跨组件的数据共享和依赖注入。

4.参考资料

参考博客


http://www.ppmy.cn/embedded/147754.html

相关文章

【NLP】第七章:Transformer原理及实操

七、Transformer 看本文前一定一定要先看注意力机制篇章&#xff1a;【NLP】第五章&#xff1a;注意力机制Attention-CSDN博客 和位置编码偏置&#xff1a;【NLP】第六章&#xff1a;位置编码Positional Encoding-CSDN博客 本文对这俩部分的讲解是掠过的&#xff01;因为注意力…

Spring(三)-SpringWeb-概述、特点、搭建、运行流程、组件、接受请求、获取请求数据、特殊处理、拦截器

文章目录 一、SpringWeb概述 二、SpringWeb特点 三、搭建SpringWeb&#xff08;在web项目中&#xff09; 1、导包 2、在web.xml文件中配置统一拦截分发器 DispatcherServlet 3、开启 SpringWEB 注解 4、处理器搭建 四、SpringWeb运行流程 五、SpringWeb组件 1、前端控…

优化Lua-cURL:减少网络请求延迟的实用方法

Lua-cURL作为一个轻量级的HTTP客户端库&#xff0c;它在Lua环境中提供了对cURL的封装&#xff0c;使得网络请求变得简单快捷。然而&#xff0c;网络请求延迟仍然是一个需要关注和解决的问题。本文将探讨如何通过优化Lua-cURL来减少网络请求延迟&#xff0c;并提供一些实用的代码…

@PostConstruct注解解释!!!!

PostConstruct 注解修饰的方法是在 Bean 完成初始化后自动调用的。它是 Java EE 和 Spring 中的一种机制&#xff0c;用于在 Bean 被创建并依赖注入完成后&#xff0c;执行一些初始化的操作。 具体触发时机&#xff1a; 依赖注入完成后&#xff1a;首先&#xff0c;Spring 容器…

C++简明教程(文章要求学过一点C语言)(7)

C 引用、指针与赋值的深度剖析 一、引用的概念 引用是 C 中的一个重要特性&#xff0c;它可以看作是变量的别名。引用在创建时必须被初始化&#xff0c;这是引用的一个重要规则。因为引用本身不占用额外的内存空间&#xff0c;它只是已存在变量的别名&#xff0c;所以需要在声…

《Python版本的那些事儿》

《Python版本的那些事儿》 一、Python 版本发展历程概述1、Python 1.x 系列简介2、Python 2.x 系列特点与重要版本3、Python 3.x 系列重大更新与各版本亮点 二、Python 不同版本关键特性对比1、语法层面的变化对比2、标准库的更新与差异3、功能特性的拓展与优化对比 三、Python…

【QT实战上手之To Do】

预计实现以下功能&#xff1a; 每个待办事项前都有一个勾选框&#xff0c;可以单独勾选。支持单独删除某一项事项。支持全选删除已勾选的事项。支持清除所有事项。 界面布局 ----------------------------------------- | 输入待办事项 [____________________] | <…

凯酷全科技抖音电商服务的卓越践行者

在数字经济蓬勃发展的今天&#xff0c;电子商务已成为企业增长的新引擎。随着短视频平台的崛起&#xff0c;抖音作为全球领先的短视频社交平台&#xff0c;不仅改变了人们的娱乐方式&#xff0c;也为品牌和商家提供了全新的营销渠道。厦门凯酷全科技有限公司&#xff08;以下简…