vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > Vue3  handlers 模块

Vue3解析学习handlers 模块

作者:death_ray

这篇文章主要介绍了Vue3解析学习handlers 模块的相关资料,需要的朋友可以参考下

本文基于个人对源码的理解与整理,难免存在偏差或不完整之处,如果你有更深入的见解或发现错误,期待一起探讨与修正。

一、handlers 的核心设计目标

一句话总结:

不同数据结构,用不同的代理策略,做到“最小拦截 + 精确触发”。

响应式系统本质上是两件事:

但不同类型的数据:

因此 Vue 把代理逻辑拆成三套:

类型变更方式Proxy 能力方案
Object属性赋值可完整拦截baseHandlers
Array属性 + 方法方法无法直接拦截重写数组方法
Map/Set方法驱动只能拦截 get返回重写方法

这不是“复杂”,而是对 JavaScript 语义边界的工程妥协。

二、Object:类继承体系

Object 的 handler 在 baseHandlers.ts 中,通过类继承组织:

1. BaseReactiveHandler(抽象基类)

这是统一入口,负责:

核心职责:

访问属性 → track → 返回响应式值

2. MutableReactiveHandler(可变对象)

这是最常见的 reactive 版本:

set

触发两种操作类型:

区分 ADD / SET 的意义在于:

新增属性 ≠ 修改属性

某些依赖只关心结构变化(比如 for...in、Object.keys)。

deleteProperty

触发:

TriggerOpTypes.DELETE

has

用于:

key in obj

依赖收集:

TrackOpTypes.HAS

ownKeys

用于:

for...in / Object.keys / Reflect.ownKeys

依赖收集:

TrackOpTypes.ITERATE

这一步是很多人忽略的关键:

遍历结构本身也是依赖。

3. ReadonlyReactiveHandler(只读)

只读版本直接阻断写操作:

但 读取仍然会 track

因为只读不等于“无依赖”。

三、Array:方法重写策略

数组的问题在于:

大部分变更不是通过属性赋值,而是通过方法。

例如:

arr.push()
arr.splice()
arr.shift()

Proxy 无法直接拦截方法调用。

Vue3 的方案是:

在 get trap 中返回“重写版本”的数组方法。

arrayInstrumentations.ts

返回“重写版本”的方法对象。

当访问数组方法时:

proxy.push

BaseReactiveHandler 的 get trap 会判断:

是不是数组?
是不是被重写的方法?

如果是:

→ 返回”重写版本“方法

这些方法内部:

这就是:

用函数包装模拟“方法拦截”。

四、Map / Set:工厂函数体系

集合类型比数组更极端:

所有变更都通过方法。

map.set()
map.delete()
set.add()

Proxy 能拦截的只有:

get

因此 Vue 采用纯工厂函数模式,而不是类继承。

1. 只拦截 get

collectionHandlers 的策略:

get → 返回重写后的方法

和数组类似,但更彻底。

2. 四种 handler 组合

创建导出 4 个全局代理对象:

这些不是手写的,而是通过:

createInstrumentationsGetter(isReadonly, shallow)

动态生成。

3. createInstrumentations 核心工厂

这个工厂函数负责:

关键点:

ReactiveFlags.RAW → 拿到原始数据

避免代理套代理导致的递归问题。

五、Track / Trigger 的精细控制

这是 Vue 3 响应式系统的灵魂改进之一。

读取操作被分为:

写入操作被分为:

它们不是简单的一对一关系。

精确触发的意义

关键规则:

并不是所有写操作都应该触发所有依赖。

例如:

如果不区分:

任何写操作 → 全部 effect 触发

这会导致:

Vue 2 的响应式就属于粗粒度触发。

Vue 3 的 handlers 设计本质是:

把“读类型”和“写类型”建立映射关系。

到此这篇关于Vue3解析学习handlers 模块的文章就介绍到这了,更多相关Vue3 handlers 模块内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文