vue3探索——组件通信之依赖注入
背景
通常情况下,当我们需要从父组件向子组件传递数据时,会使用 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探索——组件通信之依赖注入的更多相关文章
- Vue3 父子组件通信
1.父传子父组件:在子组件上通过 v-bind绑定属性子组件:先定义下基本类型,然后通过setup的第一个参数取获取传过来的值(详细代码见下面)2.子传父父组件:在子组件上绑定一个事件,并定义回调子组 ...
- angular2系列教程(八)In-memory web api、HTTP服务、依赖注入、Observable
大家好,今天我们要讲是angular2的http功能模块,这个功能模块的代码不在angular2里面,需要我们另外引入: index.html <script src="lib/htt ...
- ASP.NET Core 在 JSON 文件中配置依赖注入
前言 在上一篇文章中写了如何在MVC中配置全局路由前缀,今天给大家介绍一下如何在在 json 文件中配置依赖注入. 在以前的 ASP.NET 4+ (MVC,Web Api,Owin,SingalR等 ...
- angular 依赖注入
依赖注入 依赖注入(DI)是一个经典的设计模式, 主要是用来处理组件如何获得依赖的问题.关于DI,推荐阅读Martin Flower的文章(http://martinfowler.com/art ...
- (五)Angularjs - 依赖注入
如何找到API? AngularJS提供了一些功能的封装,但是当你试图通过全局对象angular去 访问这些功能时,却发现与以往遇到的库大不相同. 比如,AngularJS暴露了一个全局对象:angu ...
- AngularJS应用开发思维之3:依赖注入
找不到的API? AngularJS提供了一些功能的封装,但是当你试图通过全局对象angular去 访问这些功能时,却发现与以往遇到的库大不相同. $http 比如,在jQuery中,我们知道它的AP ...
- windows service宿主web api使用"依赖注入"和“控制反转”的技术实践
前言 自从几年前抛弃wcf,使用web api 来做服务器端开发之后,就不再迷惑了.但是因为本来从事传统行业管理软件开发,一般都以分布式应用开发为主.纯BS还是比较少,于是比较喜欢用windows s ...
- webapi框架搭建-依赖注入之autofac
前言 c#的依赖注入框架有unity.autofac,两个博主都用过,感觉unity比较简单而autofac的功能相对更丰富(自然也更复杂一点),本篇将基于前几篇已经创建好的webapi项目,引入au ...
- [译]ASP.NET Core依赖注入深入讨论
原文链接:ASP.NET Core Dependency Injection Deep Dive - Joonas W's blog 这篇文章我们来深入探讨ASP.NET Core.MVC Core中 ...
- Angular4学习笔记(四)- 依赖注入
概念 依赖注入是一种设计思想,并不是某一类语言所特有的,因此可以参考开涛大神关于学习Java语言的Spring框架时对其的解释: DI-Dependency Injection,即"依赖注入 ...
随机推荐
- 【论文笔记】Deeplab系列
[深度学习]总目录 DeepLab系列是谷歌团队提出的一系列语义分割算法.DeepLab v1于2014年推出,随后2017到2018年又相继推出了DeepLab v2,DeepLab v3以及Dee ...
- 2019年蓝桥杯C/C++大学B组省赛真题(等差数列)
题目描述: 数学老师给小明出了一道等差数列求和的题目.但是粗心的小明忘记了一部分的数列,只记得其中N 个整数. 现在给出这N 个整数,小明想知道包含这N 个整数的最短的等差数列有几项? 输入格式 输入 ...
- ODOO13 之十 :Odoo 13开发之后台视图 – 设计用户界面
Odoo 13开发之后台视图 – 设计用户界面 本文将学习如何为用户创建图形化界面来与图书应用交互.我们将了解不同视图类型和小组件(widgets)之间的差别,以及如何使用它们来提供更优的用户体验. ...
- 前端vue uni-app列表组件 list组件,简单好用
快速实现uni-app列表组件 list组件,简单好用; 下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=12675 效果图如下: ...
- Python开发中自动化构建项目结构样式
摘要:在项目开发过程中,一个良好的项目结构对于团队的协作和代码的可维护性起着重要作用.通过使用自动生成项目结构文字样式的工具.不仅节省了手动编写项目结构的麻烦,还确保了结构的一致性和准确性. 本文分享 ...
- Python 引用问题 - ImportError: attempted relative import with no known parent package
问题描述 近日在尝试引用其他文件的代码时,遇到了错误: ImportError: attempted relative import with no known parent package. 问题大 ...
- 详解在Linux中修改Tomcat使用的jdk版本
问题分析 由于部署个人项目使用了openjdk11,但是我之前安装的是jdk1.8,jdk版本升级的后果就是,tomcat运行的时候报一点小bug(因为之前安装tomcat默认使用了系统的jdk版本) ...
- Blazor资源大全,很棒的Blazor
Blazor资源大全 一个收集了很棒的Blazor资源的集合. Blazor是一个使用C#/Razor和HTML在浏览器中运行的.NET Web框架. 欢迎贡献!请先查看贡献指南.感谢所有的贡献者,你 ...
- 使用Stable Diffusion制作AI数字人视频的简明教程
基本方法 搞一张照片,搞一段语音,合成照片和语音,同时让照片中的人物动起来,特别是头.眼睛和嘴. 语音合成 语音合成的方法很多,也比较成熟了,大家可以选择自己方便的,直接录音也可以,只要能生成一个语音 ...
- KVM VM set net moel virtio and mulltiqueues
check $ qemu-kvm -net nic,model=help qemu: Supported NIC models: ne2k_pci,i82551,i82557b,i82559er,rt ...