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

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 能够实现跨层级数据传递和数据的自动更新,使得组件间的数据通信更加灵活和高效。

原文地址:https://blog.csdn.net/weixin_45825917/article/details/146327812
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.kler.cn/a/589553.html

相关文章:

  • 光猫 和 全光 WiFi
  • conda、poetry,pip相关
  • vue3 + css 列表无限循环滚动+鼠标移入停止滚动+移出继续滚动
  • SOC与电压的关系
  • [新能源]新能源汽车快充与慢充说明
  • GitHub Copilot 在 VS Code 上的终极中文指南:从安装到高阶玩法
  • Python学习第十九天
  • C++初阶——类和对象(四) 拷贝构造函数、赋值运算符重载函数
  • 单元测试、注解
  • EasyExcel动态拆分非固定列Excel表格
  • ZVA-Z90,罗德与施瓦茨毫米波变换器
  • 边缘端设备开发流程全解
  • uniapp-x web 开发警告提示以及解决方法
  • Rust + WebAssembly 开发环境搭建指南
  • 蓝桥杯 第五天 2021 国赛 第 5 题 最小权值
  • 使用BLSTM自动评估句子级构音障碍的可理解性
  • ssh命令
  • QVariant:Qt中万能类型的使用与理解
  • python中多重继承和泛型 作为模板让子类实现具体业务逻辑
  • Linux错误(2)程序触发SIGBUS信号分析