Vue3 依赖注入provide与inject

news2024/11/15 17:48:28

简介

        关于provide与inject下面是vue官网上的一些介绍

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

       

注意,虽然这里的 <Footer> 组件可能根本不关心这些 props,但为了使 <DeepChild> 能访问到它们,仍然需要定义并向下传递。如果组件链路非常长,可能会影响到更多这条路上的组件。这一问题被称为“prop 逐级透传”,显然是我们希望尽量避免的情况。

provide 和 inject 可以帮助我们解决这一问题 [1]。一个父组件相对于其所有的后代组件,会作为依赖提供者。任何后代的组件树,无论层级有多深,都可以注入由父组件提供给整条链路的依赖。

一个小栗子 

        创建一个跟组件,跟组件提供了三个数据源:let message、const mesRef、const mesReactive,后两者为ref、reactive类型的值,代码如下:

<template>
  <div class="box">
    <div class="show">第一层组件显示的message的值:{{ message }}</div>
    <div class="show">第一层组件显示的mesRef的值:{{ mesRef }}</div>
    <div class="show">第一层组件显示的mesReactive的值:{{ mesReactive }}</div>
    <div>
      <div>第一层组件引入第二层组件</div>
      <midassem></midassem>
    </div>
    <div class="changeMsg">
      <div class="change" @click="changeValue('one')">change message value</div>
      <div class="change" @click="changeValue('two')">change mesRef value</div>
      <div class="change" @click="changeValue('three')">change mesReactive value</div>
    </div>
  </div>
</template>
<script setup>
import { ref, reactive } from 'vue';
import { provide } from 'vue';
import midassem from './assembly/midassem.vue';

let message = "来自第一层父组件的消息";
const mesRef = ref("来自第一层父组件的响应式消息");
const mesReactive = reactive({name: "alisa", time: "2024.3.15"});

let changeNum = 0;

// 使用provide在父组件中为后代组件提供数据
// 提供一个常量
provide('message', message);

// 提供一个响应式常量
provide('refmsg', mesRef);

// 提供一个reactive响应式对象
provide('reactivemsg', mesReactive);

/* 事件回调 */
const changeValue = (tag) => {
  changeNum++;
  if (tag === "one") {
    message = message + "-" + changeNum;
  }else if(tag === "two") {
    mesRef.value = mesRef.value + "-" + changeNum;
  }else if(tag === "three"){
    mesReactive.value = mesReactive.value + "-" + changeNum;
  }
}
</script>
<style scoped lang="less">
.box {
  display: flex;
  flex-direction: column;

  .show {
    background-color: rgb(109, 144, 166);
    margin: 20px;
    padding: 20px;
  }

  .changeMsg {
    display: flex;
    flex-direction: row;
    margin: 20px;
    padding: 20px;

    .change {
      background-color: rgb(215, 146, 102);
      font-size: 16px;
      padding: 20px;
      margin-right: 20px;
      width: 380px;
      text-align: center;
    }
  }
}
</style>

创建一个跟组件的子组件midassem,用于展示它的一个子组件lastassem,代码如下:

<template>
  <div class="box">
    <div>第二层组件,加载最后一层组件如下</div>
    <div>
      <lastassem></lastassem>
    </div>
  </div>
</template>
<script setup>
import lastassem from './lastassem.vue'
</script>
<style scoped>
.box {
  display: flex;
  flex-direction: column;
}
</style>

创建子组件lastassem,用于接收根组件provide的值,代码如下:

<template>
  <div class="box">
    <div>最深层组件获取的数据:</div>
    <div class="show">第一级组件的常量值:message = {{ message }}</div>
    <div class="show">第一层组件的ref响应式值: refMsg = {{ refMsg }}</div>
    <div class="show">第一层组件的reactive响应式对象:reactiveMsg = {{ reactiveMsg }}</div>
  </div>
</template>
<script setup>
import { inject } from 'vue';

// 接收第一层组件的常量值
const message = inject('message');

// 接收第一层组件的ref响应式值
const refMsg = inject('refmsg');

// 接收第一层组件的reactive响应式值
const reactiveMsg = inject('reactivemsg');

</script>
<style scoped lang="less">
.box {
  display: flex;
  flex-direction: column;

  .show {
    background-color: aquamarine;
    margin: 20px;
    padding: 20px;
  }
}

</style>

 看一下运行后的效果图(屏幕比较小把浏览器展示的图截成了两张):

点击下方的三个button,会分别改变根组件提供的那三个值。

青绿色的部分为子组件lastassem从根组件获取的值,值得注意的是:根组件中的ref与reactive类型的值发生改变时,子组件lastassem展示的在页面上的值也响应式的发生了改变

一些优化的技巧

        但如果你正在构建大型的应用,包含非常多的依赖提供,或者你正在编写提供给其他开发者使用的组件库,建议最好使用 Symbol 来作为注入名以避免潜在的冲突。

        我们通常推荐在一个单独的文件中导出这些注入名 Symbol,下面把上面的代码优化了一下,新建了一个symbols.js文件,专门用于存储symbol创建的key值:

/*
 如果你正在构建大型的应用,包含非常多的依赖提供,或者你正在编写提供给其他开发者使用的组件库,
建议最好使用 Symbol 来作为注入名以避免潜在的冲突。
*/
export const myAssemKey = Symbol();

   然后把根组件和lastassem组件的代码优化下,如下:

import { myAssemKey } from './utils/symbols.js';

const mesReactive = reactive({name: "alisa", time: "2024.3.15"});

// 通过Symbol作为key提供数据源
provide(myAssemKey, symbolMessage);
import { myAssemKey } from '../utils/symbols.js';

// 接收第一层组件使用symbol作为key值提供的数据源
const symbolMessage = inject(myAssemKey);

        下图为展示的新的图:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1528289.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Flask开发实战】防火墙配置文件解析(二)之shell读取内容

一、前言 上一篇文章中&#xff0c;介绍了防火墙配置文件包含的基本元素和格式样式&#xff0c;并模拟了几组有代表性的规则内容&#xff0c;作为基础测试数据。在拿到基础测试数据后&#xff0c;关于我们最终想解析成的数据是什么样式的&#xff0c;其实不难看出&#xff0c;…

GateWay路由规则

Spring Cloud GateWay 帮我们内置了很多 Predicates功能&#xff0c;实现了各种路由匹配规 则&#xff08;通过 Header、请求参数等作为条件&#xff09;匹配到对应的路由 1 时间点后匹配 server:port: 8888 spring:application:name: gateway-servicecloud:nacos:discovery:…

四.排序(冒泡/选择)

目录 11-排序介绍 常见排序算法: 12-冒泡排序介绍 代码要求: 思路: 13-冒泡排序 代码: 14-选择排序 简单写法: 好的写法: 11-排序介绍 排序&#xff1a;将一组“无序”的记录序列调整为“有序”的记录序列。 列表排序&#xff1a;将无序列表变为有序列表 输入&#…

C++第七弹---类与对象(四)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】 目录 1、拷贝构造函数 1.1、概念 1.2、特征 2、运算符重载 2.1、等号运算符重载 总结 1、拷贝构造函数 1.1、概念 在现实生活中&#xff0c;可能…

【C++】手撕AVL树

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;能直接手撕AVL树。 > 毒鸡汤&#xff1a;放弃自…

Java安全基础 必备概念理解

Java安全基础 关键概念汇总 文章目录 Java安全基础 关键概念汇总前置知识1.构造器this以及包的使用2.继承3.重写/ 重载 / super4.多态5.区分和equals方法6.toString的使用7.Object的概念8.static,final,代码块static代码块final 9.动态代理10.类的动态加载1)类加载器含义&#…

leetCode刷题 17. 电话号码的字母组合

题目&#xff1a; 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 示例 1&#xff1a; 输入&#xff1a;digits "23&q…

操作系统练习-操作系统的基本概念

操作系统的基本概念 ----------------------------------------------------------------------------------------------------------------------------- 1.操作系统是扩充&#xff08; )功能的第一层系统软件 A.软件 B.裸机 C.机器语言 …

opengl日记8-opengl创建三角形

文章目录 环境直接上代码一点小总结参考 环境 系统&#xff1a;ubuntu20.04opengl版本&#xff1a;4.6glfw版本&#xff1a;3.3glad版本&#xff1a;4.6cmake版本&#xff1a;3.16.3gcc版本&#xff1a;10.3.0 直接上代码 CMakeLists.txt cmake_minimum_required(VERSION 2…

STM32CubeIDE基础学习-KEY按键输入实验

STM32CubeIDE基础学习-KEY按键输入实验 文章目录 STM32CubeIDE基础学习-KEY按键输入实验前言第1章 硬件介绍第2章 工程配置2.1 工程外设配置部分2.2 生成工程代码部分 第3章 代码编写第4章 实验现象总结 前言 前面学习了GPIO作为输出功能的实验&#xff0c;现在来学习GPIO作为…

【LIMS】微服务

目录 一、服务解决方案-Spring Cloud Alibaba1.1选用原因&#xff08;基于Spring Cloud Alibaba的试用场景&#xff09;1.2 核心组件使用前期规划 部署 nacos部署 mino使用JavaFreemarker模板引擎&#xff0c;根据XML模板文件生成Word文档使用JavaFlowable 工作流引擎前端 -vue…

C++初阶:string类的模拟自实现

目录 1. 引子2. 自实现string类功能模块3. string类功能模块的具体实现3.1 默认成员函数3.2 遍历访问相关成员函数3.3 信息插入相关成员函数3.4 信息删除3.5 信息查找3.6 非成员函数3.7 杂项成员函数 4. 补充知识 1. 引子 通过对string类的初步学习&#xff0c;没有对知识进行较…

记一次 .NET某施工建模软件 卡死分析

一&#xff1a;背景 1. 讲故事 前几天有位朋友在微信上找到我&#xff0c;说他的软件卡死了&#xff0c;分析了下也不知道是咋回事&#xff0c;让我帮忙看一下&#xff0c;很多朋友都知道&#xff0c;我分析dump是免费的&#xff0c;当然也不是所有的dump我都能搞定&#xff…

旅游行业分析及媒体邀约资源汇总

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 酒店旅游行业分析及媒体邀约资源汇总是两个相对独立但又相互关联的领域。下面将分别对这两个方面进行概述。 酒店旅游行业分析 1. 市场概况 市场规模&#xff1a;评估市场的总价值、增长…

【python】学习笔记04-函数

4.1 函数介绍 1. 函数是&#xff1a; 组织好的、可重复使用的、用来实现特定功能的代码段 2. 使用函数的好处是&#xff1a; • 将功能封装在函数内&#xff0c;可供随时随地重复利用 • 提高代码的复用性&#xff0c;减少重复代码&#xff0c;提高开发效率 4.2 函数的定义 …

视频桥接芯片#LT8912B适用于MIPIDSI转HDMI+LVDS应用方案,提供技术支持。

1. 概述 Lontium LT8912B MIPI DSI 转 LVDS 和 HDMI 桥接器采用单通道 MIPI D-PHY 接收器前端配置&#xff0c;每通道 4 个数据通道&#xff0c;每个数据通道以 1.5Gbps 的速度运行&#xff0c;最大输入带宽高达 6Gbps。 对于屏幕应用&#xff0c;该桥接器可解码 MIPI DSI 18bp…

聚合音乐网-播放器网站源码

源码简介 MKOnlineMusicPlayer 是一款全屏的音乐播放器 UI 框架&#xff08;为避免侵权&#xff0c;已移除所有后端功能&#xff09;。 前端界面参照 QQ 音乐网页版进行布局&#xff0c;同时采用了流行的响应式设计&#xff0c;无论是在PC端还是在手机端&#xff0c;均能给您…

Excel之数据透视表

数据透视&#xff1a;逻辑理解与制作步骤 一、创建数据透视表 1、创建数据透视表&#xff1a;每列必须有表头 &#xff08;1&#xff09;选择要创建数据透视表的数据------插入----选择数据透视表 &#xff08;2&#xff09;选择现有工作表然后点击目标表选择合适的位置插入…

工控机丨工业平板电脑丨工业计算机丨物流行业应用

随着物流业的发展&#xff0c;工控机在物流领域的应用越来越广泛。工控机是指用于控制工业自动化和机器 人技术的计算机&#xff0c;具有高稳定性、高性能和高可靠性等特点。下面将从几个方面介绍工控机在物流行业中的应用。 一、物流信息管理 工控机可以用于物流信息管理&am…

LLM流式方案解决方案和客户端解决方案

背景 接上一篇《LLM大模型统一封装接口解决方案》架构确定后&#xff0c;流式方案非常规请求&#xff0c;需要特殊处理。 本解决方案就是针对上一篇中所需要的流式&#xff08;打字机效果进行编码&#xff09; 什么是SSE SSE&#xff08;Server-Sent Events&#xff0c;服务器发…