当前位置: 首页 > news >正文

vue3学习源码笔记(小白入门系列)------provide和 inject 跨层级数据传递原理

目录

  • 前言
    • provide
    • inject
  • 总结

前言

需要从父组件向子组件传递数据时,会使用 props。对于层级不深的父子组件可以通过 props 透传数据,但是当父子层级过深时,数据透传将会变得非常麻烦和难以维护。
而依赖注入则是为了解决 prop 逐级透传 的问题而诞生的,父组件 provide 需要共享给子组件的数据,子组件 inject 使用需要的父组件状态数据,而且可以保持响应式。

使用例子

// 父组件
import { provide, ref } from 'vue'
const msg = ref('hello')
provide(/* 注入名 */ 'message', /* 值 */ msg)//子组件使用
import { inject } from 'vue' 
const message = inject('message')

当传入的数据 是响应式数据时, 源数据被修改后 就会派发更新。 所有使用的该数据 (被依赖收集的)组件都会触发更新

provide


export function provide<T, K = InjectionKey<T> | string | number>(key: K,value: K extends InjectionKey<infer V> ? V : T
) {// 必须在setup 方法体 使用if (!currentInstance) {if (__DEV__) {warn(`provide() can only be used inside setup().`)}} else {// 获取当前组件实例上的 provides 对象let provides = currentInstance.provides// 获取父组件实例上的 provides 对象const parentProvides =currentInstance.parent && currentInstance.parent.provides// 一般只有 根组件创建时 两者不等 不需要将子组件的provides 原型指向 父组件的providesif (parentProvides === provides) {provides = currentInstance.provides = Object.create(parentProvides)}// TS doesn't allow symbol as index typeprovides[key as string] = value}
}

看下 instance 初始化时 provides是怎么创建的

 const instance: ComponentInternalInstance = {uid: uid++,vnode,type,parent,appContext,root: null!, // to be immediately setnext: null,subTree: null!, // will be set synchronously right after creationeffect: null!,update: null!, // will be set synchronously right after creationscope: new EffectScope(true /* detached */),render: null,proxy: null,exposed: null,exposeProxy: null,withProxy: null,// 初始化 provides (根组件的parent为null 原型链就会指向 app实例上的 provides)provides: parent ? parent.provides : Object.create(appContext.provides),...
}

关系图:

在这里插入图片描述

inject

export function inject(key, defaultValue, treatDefaultAsFactory = false) {// 获取当前组件实例const instance = currentInstance || currentRenderingInstanceif (instance) {// 获取父组件上的 provides 对象const provides =instance.parent == null? instance.vnode.appContext && instance.vnode.appContext.provides: instance.parent.provides// 如果能取到,则返回值if (provides && key in provides) {return provides[key]} else if (arguments.length > 1) {// 返回默认值return treatDefaultAsFactory && isFunction(defaultValue)// 如果默认内容是个函数的,就执行并且通过call方法把组件实例的代理对象绑定到该函数的this上? defaultValue.call(instance.proxy): defaultValue}
}

核心也就是从当前组件实例的父组件上取 provides 对象,然后再查找父组件 provides 上有没有对应的属性。因为父组件的 provides 是通过原型链的方式和父组件的父组件进行了关联,如果父组件上没有,那么会通过原型链的方式再向上取,这也实现了不管组件层级多深,总是可以找到对应的 provide 的提供方数据

总结

在执行 provide 的时候,会将父组件的的 provides 关联成当前组件实例 provides 对象原型上的属性,当在 inject 获取数据的时候,则会根据原型链的规则进行查找,找不到的话则会返回用户自定义的默认值

相关文章:

vue3学习源码笔记(小白入门系列)------provide和 inject 跨层级数据传递原理

目录 前言provideinject 总结 前言 需要从父组件向子组件传递数据时&#xff0c;会使用 props。对于层级不深的父子组件可以通过 props 透传数据&#xff0c;但是当父子层级过深时&#xff0c;数据透传将会变得非常麻烦和难以维护。 而依赖注入则是为了解决 prop 逐级透传 的问…...

【Python深度学习】目标检测和语义分割的区别

在计算机视觉领域&#xff0c;语义分割和目标检测是两个关键的任务&#xff0c;它们都是对图像和视频进行分析&#xff0c;但它们之间存在着明显的区别。本文将通过图像示例&#xff0c;详细阐述语义分割和目标检测之间的差异。 一、基本概念 1.1 语义分割&#xff08;Semantic…...

取消加考!自考专业调整,2026年起执行新计划!

就在2023年10月7日&#xff0c;广东省教育考试院发布《关于广东省高等教育自学考试专业调整有关事项的通知》&#xff0c;自学考试迎来新变化&#xff0c;本次专业调整政策性强&#xff0c;涉及面广&#xff0c;持续时间长&#xff0c;一起来看看具体说明~ 关于广东省高等教育自…...

项目串讲(后端)要讲哪些东西?

刚进入一家公司&#xff0c;leader说给你几天时间&#xff0c;对咱们的公司的项目熟悉熟悉&#xff0c;做一个串讲吧。我很慌&#xff0c;没有串讲过&#xff0c;啥也不知道&#xff0c;不知道该怎么写&#xff0c;不知道讲出来leader满不满意&#xff0c;这些都是我在串讲前的…...

区块链技术在供应链管理中的创新应用

区块链技术以其独特的不可篡改和透明性特点&#xff0c;正在逐步改变供应链管理的传统模式。本文将探讨区块链技术在供应链管理中的创新应用及其带来的效益。 区块链技术的出现为许多行业带来了创新的可能&#xff0c;其中之一就是供应链管理。通过区块链技术&#xff0c;企业可…...

tcp/ip协议2实现的插图,数据结构2 (9 - 章)

&#xff08;20&#xff09; 20 九章1 IP选项处理 ip_dooptions &#xff08;21&#xff09;...

嵌入式Linux裸机开发(六)EPIT 定时器

系列文章目录 文章目录 系列文章目录前言介绍配置过程前言 前面学的快崩溃了,这也太底层了,感觉学好至少得坚持一整年,我决定这节先把EPIT学了,下面把常见三种通信大概学一下,直接跳过其他的先学移植了,有些太多了内容。 介绍 EPIT(Enhanced Periodic Interrupt Timer…...

如何批量导出文件名?

如何批量导出文件名&#xff1f;在电商行业从事工作的一些同事可能经常会遇到这样的问题&#xff1a;需要将产品文件夹中的所有图片或产品名称导出到Excel工作表&#xff0c;在工作表中创建这些名称的超链接&#xff0c;并且可能会为每个产名称的后面填写一些相关信息&#xff…...

sort排序

后端返回字段&#xff0c;前端用sort进行正序排序 init() {this.formLoading true;GetAllGalleryTestLevelTypeInfos().then((res) > {res.data.sort((a,b)>{return a.serial_number-b.serial_number})this.data res.data;console.log( this.data," serial_number…...

缓存的力量:提升API性能和可扩展性

缓存是将频繁访问的数据或资源存储在临时存储位置(例如内存或磁盘)的过程&#xff0c;以提高检索速度并减少重复处理的需要。 缓存的好处 提高性能&#xff1a;缓存消除了每次从原始源检索数据的需要&#xff0c;从而提高了响应时间并减少了延迟。减少服务器负载&#xff1a;通…...

部署vSAN相关的名词解释 几句话概括

vSphere vCenter ESXI vSphere 和一些软件的集合 是一个软件的集合。他包括了 vCenter, ESXi 和 vSphere 等。所以&#xff0c;这些软件联合起来就是 vSphere。vSphere 不是一个你可以安装使用的软件。它只是一个包含其它组件的集合。 ESXi 一个装在物理机上的系统管理程序…...

【C++】进阶模板

模板进阶 一、非类型模板参数二、模板的特化1. 函数模板的特化2. 类模板特化3. 模板特化的应用 三、模板的分离编译1. 分离编译2. 模板的分离编译3. 解决方法 四、模板总结 我们在 初识模板 中已经初步接触过模板了&#xff0c;下面我们开始更进一步学习模板。 一、非类型模板…...

易点易动设备管理系统:打通采购管理的智能化设备管理解决方案

在现代企业的运营中&#xff0c;设备管理是一个关键的环节。传统的设备管理方法往往效率低下&#xff0c;导致设备故障频发、巡检和维修工作不协调&#xff0c;备件管理不规范。为了解决这些问题&#xff0c;我们引入了易点易动设备管理系统&#xff0c;它能够全面管理设备的生…...

成集云 | 管家婆ERP集成金蝶云星辰 | 解决方案

源系统成集云目标系统 ​ 编辑 方案介绍 管家婆ERP系统是一个全面而灵活的企业资源计划平台&#xff0c;旨在帮助企业优化和自动化其业务流程&#xff0c;从而提高效率和生产力。该系统集成了从供应链管理、生产管理、财务管理到人力资源管理等所有企业运营方面的功能&#x…...

Django开发之进阶篇

Django进阶篇 一、Django学习之模板二、Django学习之中间件默认中间件自定义中间件 三、Django学习之ORM定义模型类生成数据库表操作数据库添加查询修改删除 一、Django学习之模板 在 Django 中&#xff0c;模板&#xff08;Template&#xff09;是用于生成动态 HTML&#xff…...

【C++】:类和对象(3)

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家解读一下有关Linux的基础知识点&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精通 数…...

windows创建服务:更新服务信息乱码问题(ChangeServiceConfig)

因为小项目需要创建windows服务&#xff0c;安装微软官方示例一切都挺顺利&#xff0c;代码运行后发现配置的信息在系统里显示乱码。打开注册表发现的确是乱码。这就排除软件读取得问题&#xff0c;而是调用ChangeServiceConfig系统函数写入时就发生了乱码。让我在网上查找了一…...

Spark 9:Spark 新特性

Spark 3.0 新特性 Adaptive Query Execution 自适应查询(SparkSQL) 由于缺乏或者不准确的数据统计信息(元数据)和对成本的错误估算(执行计划调度)导致生成的初始执行计划不理想&#xff0c;在Spark3.x版本提供Adaptive Query Execution自适应查询技术&#xff0c;通过在”运行…...

Angular+html+js前端加载生命周期

参考&#xff1a;document.readyState - Web API 接口参考 | MDN (mozilla.org) 第一步&#xff0c;JS生命周期第一步 文档加载中状态&#xff0c;document.readyState loading 第二步&#xff0c;JS生命周期第二步 可交互状态&#xff0c;document.readyState interacti…...

社区投稿| 以安全视角,深度剖析 Sui Staking 与 LSD

本篇技术研报由 MoveBit 研究团队的 Jason 撰写 #1 Sui Staking 介绍 1.1 Sui 网络概述 Sui 网络由一组独立的验证者运行&#xff0c;每个验证者在自己的机器或集群上运行独立的 Sui 软件实例。 Sui 采用委托权益证明&#xff08;DPoS&#xff09;来确定哪些验证者参与网络…...

AM@邻域@极限定义中的符号说明

文章目录 abstract邻域&#x1f47a;邻域中心和半径去心邻域 ϵ , δ \epsilon,\delta ϵ,δ的意义各种极限定义的共同点几何意义极限定义中的极限过程临界值 ϵ \epsilon ϵ的选取&#x1f47a; 概念辨析&#x1f47a;无限接近不同于越来越接近例例 越来越接近推不出无限接近 …...

论Oracle兼容性,我们需要做什么

作者介绍&#xff1a;王海峰&#xff0c;数据库系统架构师&#xff0c;YashanDB SQL开发负责人&#xff0c;10年以上数据库内核技术开发经验。 Oracle兼容性是目前国产数据库的关键任务之一&#xff0c;其直接影响到商业迁移的成本和竞争力。 我们经常发现&#xff0c;部分国产…...

你知道多号发圈的同时并延迟评论的方式吗?

你知道多号发圈的同时并延迟评论的方式吗&#xff1f; 其实很简单。 步骤1&#xff1a;编辑好朋友圈内容 步骤2&#xff1a;设置延迟评论 步骤3&#xff1a;选择多个号发圈 通过以上3个步骤&#xff0c;就可以实现多号发圈的同时并延迟评论。 在发布朋友圈前&#xff0c;只需要…...

【BugBounty】记一次XSS绕过

前言 最近一直在看国外的赏金平台&#xff0c;绕waf是真的难受, 记录一下绕过的场景。 初步测试 一开始尝试XSS&#xff0c;发现用户的输入在title中展示&#xff0c;那么一般来说就是看能否闭合&#xff0c;我们从下面图中可以看到&#xff0c;输入尖括号后被转成了实体。 …...

Linux文件目录结构详解:根目录和常见子目录介绍

文章目录 引言1. 什么是Linux文件目录结构2. Linux文件系统的重要性 根目录&#xff08;/&#xff09;2.1 根目录的作用和特点2.2 根目录下常见目录的介绍 /bin 目录3.1 /bin 目录的作用和内容3.2 常见的可执行命令示例 /etc 目录4.1 /etc 目录的作用和内容4.2 配置文件的存放位…...

知识付费小程序的推广与用户增长策略

在知识付费小程序开发完成后&#xff0c;推广和用户增长是关键的成功因素。本文将探讨一些推广策略和用户增长方法&#xff0c;并提供代码示例&#xff0c;帮助您在知识付费小程序中实施这些策略。 1. 社交媒体分享功能 在知识付费小程序中添加社交媒体分享功能&#xff0c;…...

微信小程序 获取当前屏幕的可见高宽度

很多时候我们做一下逻辑 需要用整个窗口的高度或宽度参与计算 而且很多时候我们js中拿到的单位都是px像素点 没办法和rpx同流合污 官方提供了wx.getSystemInfoSync() 可以获取到部分窗口信息 其中就包括了整个窗口的宽度和高度 wx.getSystemInfoSync().windowHeight 返回值为像…...

使用 Splashtop 驾驭未来媒体和娱乐

在当今时代&#xff0c;数字转型不再是可选项&#xff0c;而是必选项。如今&#xff0c;媒体与娱乐业处于关键时刻&#xff0c;正在错综复杂的创意、技术和远程协作迷宫之中摸索前进。过去几年发生的全球事件影响了我们的日常生活&#xff0c;不可逆转地改变了行业的运作方式&a…...

Tomcat项目启动报错

java.io.IOException: java.lang.ClassCastException: Cannot cast org.springframework.web.SpringServletContainerInitializer to javax.servlet.ServletContainerInitializer解决办法&#xff1a;可能Tomcat版本不对&#xff0c;使用7.0.90版本启动报错&#xff0c;使用8.0…...

offer

【录用通知书】 如何判断公司的好坏呢。 注意了&#xff0c;我们软件行业&#xff0c;技术管理类&#xff0c;技术类&#xff0c;产品类 好公司好企业基本都会给你说清楚&#xff0c;一项多少钱&#xff0c;加班多少钱&#xff0c;这样的 像这类公司的薪资结构复杂就要特别…...