Vue数据劫持源码分析

news/2025/3/14 16:38:28/

Vue.js 3.0 中的数据劫持是通过 Proxy 实现的,而不是使用 Vue.js 2.x 中的 Object.defineProperty。Proxy 是 ES6 中引入的一个新特性,它提供了更强大的拦截和自定义操作对象的能力。

以下是 Vue.js 3.0 中数据劫持的简化版源码分析:

  1. 创建 Proxy 实例

在 Vue.js 的代码中,会通过 reactive 函数来创建一个 Proxy 实例。reactive 函数接收一个普通 JavaScript 对象,并返回一个 Proxy 对象,这个 Proxy 对象会拦截对目标对象的访问和修改。

// simplified version of reactive function
function reactive(obj) {return new Proxy(obj, {get(target, key) {// 拦截属性的读取操作// 在这里可以实现依赖追踪逻辑// 返回对应的属性值},set(target, key, value) {// 拦截属性的写入操作// 在这里可以实现触发更新的逻辑// 将新的属性值赋给目标对象},});
}// 创建一个普通的 JavaScript 对象
const obj = { count: 0 };// 使用 reactive 函数将对象转换为响应式对象
const reactiveObj = reactive(obj);
  1. get 拦截器

get 拦截器中,我们可以实现依赖追踪的逻辑。当访问响应式对象的某个属性时,Proxy 会触发 get 拦截器,我们可以在这里收集对应的依赖(例如,当前正在运行的组件与该属性的关联)。然后返回对应的属性值。

// simplified version of reactive function with get interceptor
function reactive(obj) {return new Proxy(obj, {get(target, key) {// 在这里实现依赖追踪的逻辑// 例如,收集对应的依赖,建立响应式依赖关系return target[key]; // 返回对应的属性值},// set 拦截器不变});
}
  1. set 拦截器

set 拦截器中,我们可以实现触发更新的逻辑。当修改响应式对象的某个属性时,Proxy 会触发 set 拦截器,我们可以在这里触发更新,通知相关的组件进行重新渲染,并将新的属性值赋给目标对象。

// simplified version of reactive function with set interceptor
function reactive(obj) {return new Proxy(obj, {get(target, key) {// get 拦截器逻辑return target[key];},set(target, key, value) {// 在这里实现触发更新的逻辑// 例如,通知相关组件进行重新渲染target[key] = value; // 将新的属性值赋给目标对象return true;},});
}

以上是 Vue.js 3.0 中数据劫持的简化版源码分析。实际的 Vue.js 源码实现涉及到更多复杂的逻辑和边界条件处理,但基本的数据劫持原理和 Proxy 的使用是类似的。通过数据劫持,Vue.js 实现了响应式系统,使得数据与视图之间建立了自动关联,从而实现了视图的自动更新。


http://www.ppmy.cn/news/974417.html

相关文章

进程信号的理解

进程信号 1. 信号的概念2. 信号的产生3. 信号的保存1. 信号其他相关常见概念2. 在内核中的表示3.信号集操作函数 4. 信号的处理(捕捉) 1. 信号的概念 信号的一生,进程信号从产生到被处理所经历的过程一共分成了三步:信号产生、信…

【Git】—— 分⽀的基本操作

目录 (一)理解分⽀ (二)创建分⽀ (三)切换分⽀ (四)合并分⽀ (五)删除分⽀ 总结 (一)理解分⽀ 本章开始介绍 Git 的杀⼿级功能之…

一键批量JSON标注转PNG图片工具V1.1,支持labelme快捷矩形、圆以及轮廓标注

上次发布了一个批量将labelme标注的json文件转换为png文件工具,但是当时只是想着自己用的,功能相当简单,一些网友使用之后跟我反馈这玩意真”垃圾“,很多情况都没有进行设想,所以在功能上很欠缺。由于小陶这几天在外地…

解决FLink:Missing required options are: slot.name

[ERROR] Could not execute SQL statement. Reason: org.apache.flink.table.api.ValidationException: One or more required options are missing.Missing required options are:slot.name解决 https://ververica.github.io/flink-cdc-connectors/release-2.4/content/connec…

Django笔记之in查询及date日期相关过滤操作

这一篇介绍关于范围,日期的筛选 inrangedateyearweekweekdayquarterhour 1、in in 对应于 MySQL 中的 in 操作,可以接受数组、元组等类型数据作为参数: Blog.objects.filter(id__in[1,2,3])对应的 SQL 是: select * from blo…

C++(一):基本数据类型

基本数据类型 基本内置类型定义变量type field value;type field(value);type field{value};type field {value}; 数学常量及函数静态类型转换 static_cast格式化字符串std::stringstreamstd::string引入三方库 fmt/core.h 字符运算auto 关键字枚举类型数据类型定义别名判断是…

Hive内部表和外部表的区别

未被 external修饰的是内部表 被 external修饰的为外部表。 区别: 内部表数据由 Hive自身管理; 外部表数据由 HDFS管理; 内部表数据存储的位置是 hive.metastore.warehouse.dir(默认:/user/hive/warehouse&#xf…

第二讲:k8s集群架构与相关组件

目录 一、相关组件 1.1 控制面板组件(master) 1.1.1 kube-apiserver 1.1.2 kube-controller-manager 1.1.3 cloud-controller-manager 1.1.4 kube-schedule 1.1.5 etcd 1.2 节点组件 1.2.1 kubelet 1.2.2 kube-proxy 1.2.3 container runtime 1.3 附加组…