背景

通常情况下,当我们需要从父组件向子组件传递数据时,会使用 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. Django中render()函数和redirect()函数

    render() 作用:render是渲染变量(结合一个给定的模板和一个给定的上下文字典)在模板中,通俗点将context的内容,加载进模板中定义的文件,通过浏览器渲染呈现. render()方法常用 ...

  2. Python连接es笔记三之es更新操作

    本文首发于公众号:Hunter后端 原文链接:Python连接es笔记三之es更新操作 这一篇笔记介绍如何使用 Python 对数据进行更新操作. 对于 es 的更新的操作,不用到 Search() ...

  3. 玩转服务器之数据传输篇:如何快速搭建FTP文件共享服务器

    FTP 文件共享服务器介绍 FTP服务(File Transfer Protocol,FTP)是最早应用于主机之间数据传输的基本服务之一,是目前使用最广泛的文件传送协议.FTP文件共享服务器在日常办公 ...

  4. 【LeetCode.384打乱数组】Knuth洗牌算法详解

    前两天看网易面筋得知网易云的随机歌曲播放使用了这个算法,遂找题来做做学习一下 打乱数组 https://leetcode.cn/problems/shuffle-an-array/ 给你一个整数数组 ...

  5. .Net7矢量化的性能优化

    前言 矢量化是性能优化的重要技术,也是寄托硬件层面的优化技术.本篇来看下. 概括 一:矢量化支持的问题: 矢量化的System.Runtime.Intrinsics.X86.Sse2.MoveMask ...

  6. @Target元注解的使用

    @Target注解标记另外的注解用于限制此注解可以应用哪种Java元素类型.先看Java SE 8中@Target是如何声明的: package java.lang.annotation; publi ...

  7. tSNE算法在自然语言处理中的应用:文本降维和可视化

    目录 技术原理及概念 t-SNE(Toeplitz-Stochastic Neural Network)是一种常用的文本降维和可视化算法,它的核心思想是将高维文本数据映射到低维空间,同时保持数据的一致 ...

  8. 曲线艺术编程 coding curves 第十二章 超级椭圆与超级方程(Superellipses and Superformulas)

    第十三章 超级椭圆与超级方程(Superellipses and Superformulas) 原作:Keith Peters https://www.bit-101.com/blog/2022/11 ...

  9. Mysql数据库常见故障

    Mysql数据库常见故障 1.报错现象 Host is blocked because of many connection errors; unblock with 'mysqladmin flus ...

  10. .NET Core 允许跨域的两种方式实现(IIS 配置、C# 代码实现)

    〇.前言 当把开发好的 WebApi 接口,部署到 Windows 服务器 IIS 后,postman 可以直接访问到接口并正确返回,这并不意味着任务完成,毕竟接口嘛是要有交互的,最常见的问题莫过于跨 ...