背景

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

对于这种组件使用结构,vue3给我们提供了另外一种传参方式,那就是依赖注入。一个父组件相对于其所有的后代组件,会作为依赖提供者(provide)。任何后代的组件树,无论层级有多深,都可以注入(inject)由父组件提供给整条链路的依赖。

基础使用

依赖提供者provide()

provide的使用非常简单,下面给出代码。

<script setup lang="ts">
// 1-引入
import { ref, provide } from 'vue'; const param = ref(); // 2-使用
provide('mark', param);
</script>

provide()函数需要传入两个参数:

  • 第一个参数被称为注入名,可以是一个字符串或是一个 Symbol。后代组件会用注入名来查找期望注入的值。一个组件可以多次调用 provide(),使用不同的注入名,注入不同的依赖值。
  • 第二个参数是提供的值,值可以是任意类型,包括响应式的状态,比如一个 ref。提供的响应式状态使后代组件可以由此和提供者建立响应式的联系。

增强功能:除了在一个组件中提供依赖,我们还可以在整个应用层面提供依赖,类似于vue2中挂载在vue实例的原型对象上

import { createApp } from 'vue'

const app = createApp({})

app.provide(/* 注入名 */ 'message', /* 值 */ 'hello!')

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

注入inject()

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

<script setup lang="ts">
// 1-引入
import { inject } from 'vue'; // 2-使用
const param = inject('mark');
// 第二个参数可以设置注入**默认值**,防止祖先组件没有提供依赖而造成报错
const param2 = inject('mark2', '默认值');
</script>

注意,不使用<script setup> 的话,需要在setup()函数中使用provide()inject()

import { provide } from 'vue'

export default {
setup() {
provide(/* 注入名 */ 'message', /* 值 */ 'hello!')
}
}
import { inject } from 'vue'

export default {
setup() {
const message = inject('message')
return { message }
}
}

实战

// src/App.vue
<template>
<div class="dad">
<!-- 1000元 -->
<h1>我是父组件,我有{{ money }}元</h1>
<!-- 使用子组件 -->
<son />
</div>
</template> <script setup lang="ts">
// 引入子组件
import son from './components/son.vue';
// 引入vue API
import { ref, provide } from 'vue'; // 1-父组件响应式数据
const money = ref(1000); // 向后面的组件提供依赖
provide('Pmoney', money);
</script> <style lang="scss" scoped>
.dad {
width: 600px;
height: 600px;
background-color: skyblue;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
</style>
// src/components/son.vue
<template>
<div class="son">
<h2>我是子组件</h2>
<!-- 使用孙组件 -->
<grandson />
</div>
</template> <script setup lang="ts">
// 引入孙组件
import grandson from './grandson.vue';
</script> <style lang="scss" scoped>
.son {
height: 400px;
width: 400px;
background-color: pink;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
</style>
// src/components/grandson.vue
<template>
<div class="grandson">
<h3>我是孙组件,我爷爷有{{ money }}元</h3>
</div>
</template> <script setup lang="ts">
// 引入 inject
import { inject } from 'vue'; // 2-注入祖先组件的依赖
const money = inject('Pmoney');
</script> <style lang="scss" scoped>
.grandson {
width: 200px;
height: 200px;
background-color: aqua;
}
</style>

vue3探索——组件通信之依赖注入的更多相关文章

  1. Vue3 父子组件通信

    1.父传子父组件:在子组件上通过 v-bind绑定属性子组件:先定义下基本类型,然后通过setup的第一个参数取获取传过来的值(详细代码见下面)2.子传父父组件:在子组件上绑定一个事件,并定义回调子组 ...

  2. angular2系列教程(八)In-memory web api、HTTP服务、依赖注入、Observable

    大家好,今天我们要讲是angular2的http功能模块,这个功能模块的代码不在angular2里面,需要我们另外引入: index.html <script src="lib/htt ...

  3. ASP.NET Core 在 JSON 文件中配置依赖注入

    前言 在上一篇文章中写了如何在MVC中配置全局路由前缀,今天给大家介绍一下如何在在 json 文件中配置依赖注入. 在以前的 ASP.NET 4+ (MVC,Web Api,Owin,SingalR等 ...

  4. angular 依赖注入

    依赖注入    依赖注入(DI)是一个经典的设计模式, 主要是用来处理组件如何获得依赖的问题.关于DI,推荐阅读Martin Flower的文章(http://martinfowler.com/art ...

  5. (五)Angularjs - 依赖注入

    如何找到API? AngularJS提供了一些功能的封装,但是当你试图通过全局对象angular去 访问这些功能时,却发现与以往遇到的库大不相同. 比如,AngularJS暴露了一个全局对象:angu ...

  6. AngularJS应用开发思维之3:依赖注入

    找不到的API? AngularJS提供了一些功能的封装,但是当你试图通过全局对象angular去 访问这些功能时,却发现与以往遇到的库大不相同. $http 比如,在jQuery中,我们知道它的AP ...

  7. windows service宿主web api使用"依赖注入"和“控制反转”的技术实践

    前言 自从几年前抛弃wcf,使用web api 来做服务器端开发之后,就不再迷惑了.但是因为本来从事传统行业管理软件开发,一般都以分布式应用开发为主.纯BS还是比较少,于是比较喜欢用windows s ...

  8. webapi框架搭建-依赖注入之autofac

    前言 c#的依赖注入框架有unity.autofac,两个博主都用过,感觉unity比较简单而autofac的功能相对更丰富(自然也更复杂一点),本篇将基于前几篇已经创建好的webapi项目,引入au ...

  9. [译]ASP.NET Core依赖注入深入讨论

    原文链接:ASP.NET Core Dependency Injection Deep Dive - Joonas W's blog 这篇文章我们来深入探讨ASP.NET Core.MVC Core中 ...

  10. Angular4学习笔记(四)- 依赖注入

    概念 依赖注入是一种设计思想,并不是某一类语言所特有的,因此可以参考开涛大神关于学习Java语言的Spring框架时对其的解释: DI-Dependency Injection,即"依赖注入 ...

随机推荐

  1. lec-4-Introduction to Reinforcement Learning

    模仿学习imitation learning与RL的不同 模仿学习中需要有专家指导的信息 RL不需要访问专家信息 RL Definitions 奖励函数 马尔科夫决策链 只与上一个状态有关 目的 空间 ...

  2. flutter apk启动闪退问题

    今发布一个flutter apk 安装后启动时老是闪退,经过一遍又一遍查找,发现是指定了so的问题 看多次点击启动 一.比对打包后的apk 在出现该问题后也搜索了不少资料,参考过 https://bl ...

  3. aspnetcore最最简单的接口权限认证

    五月一眨眼就过去,就当凑个数吧. 场景: 一个小小的项目,需要一个后台,就展示几个列表,连用户表.角色表等都不需要设计. 之前有写过identityserver4和jwt4的demo (exercis ...

  4. 驱动开发:内核实现SSDT挂钩与摘钩

    在前面的文章<驱动开发:内核解析PE结构导出表>中我们封装了两个函数KernelMapFile()函数可用来读取内核文件,GetAddressFromFunction()函数可用来在导出表 ...

  5. AI 协助办公 |记一次用 GPT-4 写一个消息同步 App

    GPT-4 最近风头正劲,作为 NebulaGraph 的研发人员的我自然是跟进新技术步伐.恰好,现在有一个将 Slack channel 消息同步到其他 IM 的需求,看看 GPT-4 能不能帮我完 ...

  6. 二维数组初始化vector, 以及类型转换问题

    //二维数组的初始化1 vector<vector<float>> _box_parm(class_row_num, vector<float>(class_col ...

  7. C++面试八股文:std::string是如何实现的?

    某日二师兄参加XXX科技公司的C++工程师开发岗位第18面: 面试官:std::string用过吧? 二师兄:当然用过(废话,C++程序员就没有没用过std::string的). 面试官:std::s ...

  8. Prometheus-2:blackbox_exporter黑盒监控

    黑盒监控blackbox_exporter 前边介绍有很多exporter可以直接将metrics暴露给Prometheus进行监控,这些称为"白盒监控",那些exporter无法 ...

  9. 【WALT】scale_exec_time() 代码详解

    @ 目录 [WALT]scale_exec_time() 代码详解 代码展示 代码逻辑: 为什么归一化? ⑴ 将 CPU cycles 转换为 CPU 当前频率 ⑵ 归一化 delta [WALT]s ...

  10. spring-boot-plus2.7.12版本重磅发布,三年磨一剑,兄弟们等久了,感谢你们的陪伴

    Everyone can develop projects independently, quickly and efficiently! spring-boot-plus是一套集成spring bo ...