provide/inject源码实现

在 Vue 3 中,provide 和 inject 是通过 Vue 的响应式系统和组件实例机制实现的,底层是依赖 Vue 3 中的 Proxy 和 Reactive 来实现跨层级的数据传递和响应式绑定。以下是一个简化版的实现逻辑,帮助理解 Vue 3 中 provide 和 inject 是如何实现的。

  1. provide 的实现

provide 的核心目的是将数据存储在当前组件的上下文中,然后将这些数据传递给其后代组件。Vue 3 使用 Proxy 来实现对组件上下文的响应式管理。

基本的实现思路:

在父组件中,使用 provide 将数据存储到一个上下文对象中,父组件上下文数据存储在当前组件实例的 provides 对象中。

父组件的 provides 会暴露给子组件,子组件可以从父组件的上下文中读取提供的数据。

简化版的实现逻辑如下:

class Component {
constructor() {
this.provides = new Map(); // 存储提供的数据
}

provide(key, value) {
this.provides.set(key, value); // 设置提供的数据
}

inject(key) {
return this.provides.get(key); // 从当前组件的 provides 中获取
}
}

示例:

const parentComponent = new Component();
parentComponent.provide(‘user’, { name: ‘John’, age: 30 });

const childComponent = new Component();
const user = childComponent.inject(‘user’); // 获取父组件提供的数据
console.log(user); // 输出: { name: ‘John’, age: 30 }

  1. inject 的实现

inject 用来从当前组件的父组件(或祖先组件)中获取提供的数据。在实际实现中,Vue 会查找组件的父链(即组件树)来查找所需的 provide 数据。

基本的实现思路:

在子组件中,使用 inject 来获取上层组件通过 provide 提供的数据。Vue 会遍历组件树,查找最近的祖先组件。

如果当前组件没有提供数据,Vue 会继续向上查找直到根组件。

class Component {
constructor(parent = null) {
this.parent = parent;
this.provides = new Map(); // 存储提供的数据
}

provide(key, value) {
this.provides.set(key, value);
}

inject(key) {
// 从当前组件开始,逐级向父组件查找数据
let currentComponent = this;
while (currentComponent) {
if (currentComponent.provides.has(key)) {
return currentComponent.provides.get(key);
}
currentComponent = currentComponent.parent;
}
return undefined; // 如果找不到提供的数据,返回 undefined
}
}

示例:

// 父组件提供数据
const parentComponent = new Component();
parentComponent.provide(‘user’, { name: ‘John’, age: 30 });

// 子组件继承父组件
const childComponent = new Component(parentComponent);

// 孙组件继承子组件
const grandchildComponent = new Component(childComponent);

// 孙组件注入父组件提供的数据
const user = grandchildComponent.inject(‘user’);
console.log(user); // 输出: { name: ‘John’, age: 30 }

  1. 响应式机制

在 Vue 3 中,provide 和 inject 采用的是基于 Proxy 的响应式系统。Vue 3 的响应式系统使用 Proxy 来监听对象的变化,确保在数据变更时能够触发视图更新。

为了实现响应式传递,Vue 会通过 reactive 来包装提供的数据,然后使用 provide 提供的值会是一个响应式对象,子组件通过 inject 获取该对象时,数据的变化会自动反应到视图中。

简化的响应式实现:

function reactive(obj) {
return new Proxy(obj, {
get(target, prop) {
console.log(Accessing ${prop}); // 打印属性访问的日志
return target[prop];
},
set(target, prop, value) {
console.log(Setting ${prop} to ${value}); // 打印属性设置的日志
target[prop] = value;
return true;
}
});
}

class Component {
constructor(parent = null) {
this.parent = parent;
this.provides = new Map();
}

provide(key, value) {
this.provides.set(key, reactive(value)); // 提供响应式数据
}

inject(key) {
let currentComponent = this;
while (currentComponent) {
if (currentComponent.provides.has(key)) {
return currentComponent.provides.get(key); // 返回响应式数据
}
currentComponent = currentComponent.parent;
}
return undefined;
}
}

示例:

// 父组件提供响应式数据
const parentComponent = new Component();
const user = { name: ‘John’, age: 30 };
parentComponent.provide(‘user’, user);

// 子组件继承父组件
const childComponent = new Component(parentComponent);

// 孙组件继承子组件
const grandchildComponent = new Component(childComponent);

// 孙组件注入父组件提供的响应式数据
const injectedUser = grandchildComponent.inject(‘user’);
injectedUser.name = ‘Jane’; // 通过代理修改数据

console.log(user.name); // 输出: Jane,数据变化自动反映

总结

Vue 3 中的 provide 和 inject 实现是基于 Proxy 的响应式系统,组件的 provides 数据是响应式的,当数据变化时,依赖这些数据的组件会自动更新。provide 用来提供数据,inject 用来注入数据,支持跨组件层级的数据共享。通过 Proxy,Vue 3 能够实现跨层级数据传递和数据的自动更新,使得组件间的数据通信更加灵活和高效。

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

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

相关文章

Unix时间戳BKP备份寄存器RTC实时时钟

Unix时间戳 Unix时间戳,也称为POSIX时间或Epoch时间,是一种在Unix和类Unix操作系统中使用的时间表示方法。它表示的是自1970年1月1日00:00:00 UTC(协调世界时)至当前时间经过的秒数,不考虑闰秒。Unix时间戳通常以秒为…

【Linux内核系列】:进程板块与文件板块的综合

🔥 本文专栏:Linux 🌸作者主页:努力努力再努力wz 💪 今日博客励志语录: 人生中成功只是一时的,失败却是人生的主旋律,但是如何面对失败却把人分成了不同的样子,有的人会被…

CellOracle|基因扰动研究基因功能|基因调控网络+虚拟干预

在gzh“生信小鹏”同步文章 论文来源: 发表期刊:Nature发表时间:2023年2月23日论文题目:Dissecting cell identity via network inference and in silico gene perturbation研究团队:Kenji Kamimoto 等,华盛顿大学医学院1. 研究背景与问题提出 细胞身份(Cell Identit…

专线、云 和 物联网(IoT)

专线、云 和 物联网(IoT) 是现代信息与通信技术(ICT)领域的三大重要组成部分,它们在企业和个人的数字化转型中扮演着关键角色。以下是对这三者的详细介绍及其相互关系: 1. 专线(Leased Line&…

[Lc14_priority_queue] 最后一块石头重量 | 数据流中的第 K 大元素 | 前K个高频单词 | 数据流的中位数

目录 1.最后一块石头的重量 题解 2.数据流中的第 K 大元素 题解 3.前K个高频单词 题解 代码 ⭕4.数据流的中位数 题解 在C中,使用标准库中的priority_queue,默认情况下它是一个最大堆(即大堆排序),这意味着最…

XSS漏洞靶场---(复现)

XSS漏洞靶场—(复现) 反射型 XSS 的特点是攻击者诱导用户点击包含恶意脚本的 URL,服务器接收到请求后将恶意脚本反射回响应页面,浏览器执行该脚本从而造成攻击,恶意脚本不会在服务器端存储。 Level 1(反射型XSS) 此漏…

2025/3.17 郭院安排会议与南京银行参访

目录 *郭院会议:服务外包*1.会遇到的问题以及解决方案2.考虑行业目前会碰到的瓶颈3.后端应该呈现处理图像的过程4.记得做报告、文档说明和视频等工作 *南京银行(鑫合易家)参访记录*1. 风险评分业务流程笔记![在这里插入图片描述](https://i-b…

Cloud Ace 宣布成为 Langfuse 亚太地区首个代理商,提供 LLM 全链路解决方案

Cloud Ace 宣布正式代理 Langfuse 产品,是 Langfuse 在亚太地区唯一的官方授权经销商,全面负责其商用许可证的销售、部署与技术支持服务。通过此次合作,Cloud Ace 将充分发挥 Langfuse 的先进技术能力与行业专业知识,为企业级客户…

Helm 的仓库管理与 Chart 搜索

在使用 Helm 管理 Kubernetes 应用的过程中,仓库管理与 Chart 搜索是两个核心功能。通过 Helm 仓库,用户可以方便地存储、分享和获取 Helm Chart,而搜索功能则帮助用户快速找到所需的 Chart。本文将详细介绍 Helm 仓库的概念、管理方法以及如…

Matlab 汽车振动多自由度非线性悬挂系统和参数研究

1、内容简介 略 Matlab 169-汽车振动多自由度非线性悬挂系统和参数研究 可以交流、咨询、答疑 2、内容说明 略 第二章 汽车模型建立 2.1 汽车悬架系统概述 2.1.1 悬架系统的结构和功能 2.1.2 悬架分类 2.2 四分之一车辆模型 对于车辆动力学,一般都是研究其悬…

免训练指标(Zero-Cost Proxies)

1. 什么是免训练指标(Zero-Cost Proxies,ZC proxies)? 免训练指标是一类 无需完整训练模型即可评估其性能的度量方法,主要用于提高 神经架构搜索(NAS) 的效率。 传统 NAS 需要训练候选架构来评…

C语言 —— 此去经年梦浪荡魂音 - 深入理解指针(卷二)

目录 1. 数组名与地址 2. 指针访问数组 3.一维数组传参本质 4.二级指针 5. 指针数组 6. 指针数组模拟二维数组 1. 数组名与地址 我们先看下面这个代码: int arr[10] { 1,2,3,4,5,6,7,8,9,10 };int* p &arr[0]; 这里我们使用 &arr[0] 的方式拿到了数…

基于Python pyscard库采集ACS ACR122U NFC读卡器数据的详细操作步骤

步骤1:安装驱动 1. 下载驱动: - 访问ACS官网的驱动下载页面:[ACR122U驱动下载](https://www.acs.com.hk/en/drivers/6/acr122u-nfc-reader/)。 - 选择适用于Windows的驱动(如 ACR122U Driver (Windows) V3.05.02.zip)…

深度学习 Deep Learning 第1章 深度学习简介

第1章 深度学习简介 概述 本章介绍人工智能(AI)和深度学习领域,讨论其历史发展、关键概念和应用。解释深度学习如何从早期的AI和机器学习方法演变而来,以及如何有效解决之前方法无法应对的挑战。 关键概念 1. 人工智能的演变 …

python实现简单的图片去水印工具

python实现简单的图片去水印工具 使用说明: 点击"打开图片"选择需要处理的图片 在图片上拖拽鼠标选择水印区域(红色矩形框) 点击"去除水印"执行处理 点击"保存结果"保存处理后的图片 运行效果 先简要说明…

软件功能性测试有哪些步骤和挑战?软件测评服务机构分享

软件功能性测试是对软件系统进行验证的一种基本方法。其主要目标是确保软件系统能够按照预期的要求和功能进行操作。从用户的角度看,功能性测试旨在检查软件是否实现了所有要求的功能,保证用户体验的顺畅与满意。 一、软件功能性测试的测试步骤   1、…

《C#上位机开发从门外到门内》3-4:基于TCP/IP的远程监控系统设计与实现

文章目录 一、项目概述二、系统架构设计三、通信协议设计四、功能模块实现五、系统安全性与稳定性六、性能优化与测试七、实际应用案例八、结论 随着信息技术的飞速发展,远程监控系统在工业自动化、智能家居、环境监测等领域的应用日益广泛。基于TCP/IP协议的远程监…

在react当中利用IntersectionObserve实现下拉加载数据

目录 一、传统的下拉加载方案 二、存在问题 1.性能较差 2.不够精确 三、IntersectionObserve版本下拉加载 1、callback 2、options 四、IntersectionObserver实例 1、Intersection的优势 2、实现思路 3、代码实现 在进行前端开发的过程中,常常会碰到下拉…

深入理解C++编程:从内存管理到多态与算法实现

C 是一门功能强大的编程语言,广泛应用于系统编程、游戏开发和高性能计算等领域。本文将通过一系列经典问题,深入探讨 C 的核心知识点,包括内存管理、多态(结合函数重载与覆盖)、多线程、TCP/IP 模型、软链接与硬链接的…

相对论之光速

然而,基础物理学的进步很少全部由实验取得。为了解实验结果背后的机制,法拉第问道,既然磁铁没有接触导线,导线中怎么会产生电流?一股电流又怎么能使指南针指针发生偏转?有某种作用因素必然在磁铁、导线和指南针之间的空隙中传递…