背景

通常情况下,当我们需要从父组件向子组件传递数据时,会使用 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. 2015年蓝桥杯C/C++大学B组省赛真题(加法变乘法)

    题目描述: 我们都知道:1+2+3+ ... + 49 = 1225 现在要求你把其中两个不相邻的加号变成乘号,使得结果为2015 比如: 1+2+3+...+10*11+12+...+27*28+2 ...

  2. 通过nc获取靶机的反弹Shell [靶机实战]

    1.环境 Kali:172.30.1.3/24 靶机(Funbox9):172.30.1.129/24 2.信息收集 通过nmap扫描此主机,我们需要获取到开放的端口以及服务的Banner 1 nma ...

  3. vst实例(2) 创建VST

    前面我们知道,创建一个虚拟树,应该首先告知VST节点数据的大小(即nodedatasize),其实在创建树结构时,这一点并不是必须的,而是如果你需要让VST的每一个节点能指向一定的数据,从而在执行树的 ...

  4. 简单了解一下国产CPU

    这几天在B站.油管上刷了一些国产芯片真实上手视频,顺便自己也梳理一下芯片的一些基本概念,以及在美国科技制裁和围堵的情况下,国产CPU的发展情况.文末有我整理的一张思维导图,hope u find it ...

  5. C温故补缺(十八):网络编程

    计算机网络 参考:TCP三次握手详解. OSI模型 简单分层: 其中,链路层还可以分出物理层和数据链路层.应用层可以分出会话层,表示层和应用层. 七层模型: 链路层:只是物理的比特流和简单封装的数据帧 ...

  6. CentOS Linux 7 配置 nginx 支持 CGI

    Nginx 本身不能执行外部程序,Nginx 处理 PHP 是通过 PHP 的 fastcgi 管理器(php-fpm)进行处理,然后 nginx 再将结果返回给用户:所以如果我们需要通过 cgi 程 ...

  7. NixOS 与 Nix Flakes 新手入门

    独立博客阅读: https://thiscute.world/posts/nixos-and-flake-basics/ 长文警告️ 本文的目标 NixOS 版本为 22.11,Nix 版本为 2.1 ...

  8. C#/VB.NET:快速而简单的免费SVG到PDF转换技巧

    在日常工作中,我们常常需要将SVG转换为PDF格式.这是因为SVG格式的图像在打印时可能会出现问题,例如失去分辨率或无法正确适应纸张大小.与此相比,PDF格式则专门用于打印和共享文档,可以确保高质量输 ...

  9. Ubuntu 16.04关闭系统自动更新

    # 背景在使用阿里云ECS服务器时,服务器CPU与内存突然增大,经过排查发现是系统自动更新导致,幸运的是不是发生在业务高峰期,为了避免出现类似的情况,决定禁用系统自动更新,可以通过手动或者定时任务的方 ...

  10. 如何从AWS中学习如何使用AWS的AmazonDynamoDB存储卷

    目录 引言 随着云计算.大数据和人工智能等技术的发展,AWS(亚马逊云)成为了备受瞩目的云计算平台之一.AWS提供了许多先进的云计算服务和功能,包括Amazon DynamoDB(Amazon Dyn ...