Vue3解析学习handlers 模块

 更新时间:2026年02月15日 15:34:52   作者:death_ray  
这篇文章主要介绍了Vue3解析学习handlers 模块的相关资料,需要的朋友可以参考下

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

一、handlers 的核心设计目标

一句话总结:

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

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

  • 依赖收集(track):读取时记录依赖

  • 副作用触发(trigger):写入时触发更新

但不同类型的数据:

  • 变更方式不同

  • 可拦截能力不同

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

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

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

二、Object:类继承体系

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

1. BaseReactiveHandler(抽象基类)

这是统一入口,负责:

  • get 拦截

  • ref 解包

  • 深/浅响应式递归

  • 依赖收集

核心职责:

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

2. MutableReactiveHandler(可变对象)

这是最常见的 reactive 版本:

set

触发两种操作类型:

  • TriggerOpTypes.ADD(新增属性)

  • TriggerOpTypes.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(只读)

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

  • set → 警告 + 不执行

  • deleteProperty → 警告 + 不执行

但 读取仍然会 track

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

三、Array:方法重写策略

数组的问题在于:

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

例如:

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

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

Vue3 的方案是:

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

arrayInstrumentations.ts

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

当访问数组方法时:

proxy.push

BaseReactiveHandler 的 get trap 会判断:

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

如果是:

→ 返回”重写版本“方法

这些方法内部:

  • 先暂停依赖收集(避免死循环)

  • 调用原始数组方法

  • 手动 trigger

这就是:

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

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

集合类型比数组更极端:

所有变更都通过方法。

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

Proxy 能拦截的只有:

get

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

1. 只拦截 get

collectionHandlers 的策略:

get → 返回重写后的方法

和数组类似,但更彻底。

2. 四种 handler 组合

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

  • mutableCollectionHandlers(深响应式)

  • shallowCollectionHandlers(浅响应式)

  • readonlyCollectionHandlers(只读)

  • shallowReadonlyCollectionHandlers(浅只读)

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

createInstrumentationsGetter(isReadonly, shallow)

动态生成。

3. createInstrumentations 核心工厂

这个工厂函数负责:

  • 构造重写后的 Map/Set 方法

  • 在方法内部访问原始对象

关键点:

ReactiveFlags.RAW → 拿到原始数据

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

五、Track / Trigger 的精细控制

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

读取操作被分为:

  • GET

  • HAS

  • ITERATE

写入操作被分为:

  • SET

  • ADD

  • DELETE

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

精确触发的意义

关键规则:

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

例如:

  • GET 依赖只关心 SET

  • ITERATE 依赖关心 ADD / DELETE

  • HAS 依赖只关心 key 是否存在

如果不区分:

任何写操作 → 全部 effect 触发

这会导致:

  • 不必要的重渲染

  • 性能雪崩

  • 副作用风暴

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

Vue 3 的 handlers 设计本质是:

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

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

相关文章

  • 关于vue-color-颜色选择器插件

    关于vue-color-颜色选择器插件

    这篇文章主要介绍了关于vue-color-颜色选择器插件,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • Vue3.0插件执行原理与实战

    Vue3.0插件执行原理与实战

    这篇文章主要介绍了Vue3.0插件执行原理与实战,Vue项目能够使用很多插件来丰富自己的功能Vue-Router、Vuex等,节省了我们大量的人力和物力,下面我们就一起来了解Vue3.0插件的原理吧,需要的小伙伴可以参考一下
    2022-02-02
  • Vue package-lock.json的作用及说明

    Vue package-lock.json的作用及说明

    这篇文章主要介绍了Vue package-lock.json的作用及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • vuejs2.0子组件改变父组件的数据实例

    vuejs2.0子组件改变父组件的数据实例

    本篇文章主要介绍了vuejs2.0子组件改变父组件的数据实例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • vue采用EventBus实现跨组件通信及注意事项小结

    vue采用EventBus实现跨组件通信及注意事项小结

    EventBus是一种发布/订阅事件设计模式的实践。这篇文章主要介绍了vue采用EventBus实现跨组件通信及注意事项,需要的朋友可以参考下
    2018-06-06
  • vue+element模态框中新增模态框和删除功能

    vue+element模态框中新增模态框和删除功能

    这篇文章主要介绍了vue+element模态框中新增模态框和删除功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-06-06
  • vue项目实现m3u8流媒体播放详细图文教程

    vue项目实现m3u8流媒体播放详细图文教程

    m3u8是一种常用的视频流媒体格式,通常用于在Web上播放视频,这篇文章主要给大家介绍了关于vue项目实现m3u8流媒体播放的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-09-09
  • 解决vue-cli + webpack 新建项目出错的问题

    解决vue-cli + webpack 新建项目出错的问题

    下面小编就为大家分享一篇解决vue-cli + webpack 新建项目出错的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03
  • vue环形进度条组件实例应用

    vue环形进度条组件实例应用

    在本文中我们给大家分享了关于vue环形进度条组件的使用方法以及实例代码,需要的朋友们跟着测试下吧。
    2018-10-10
  • Vue项目本地没有问题但部署到服务器上提示错误(问题解决方案)

    Vue项目本地没有问题但部署到服务器上提示错误(问题解决方案)

    一个 VUE 的项目在本地部署没有问题,但是部署到服务器上的时候提示访问资源的错误,遇到这样的问题如何解决呢?下面小编给大家带来了Vue项目本地没有问题但部署到服务器上提示错误的解决方法,感兴趣的朋友一起看看吧
    2023-05-05

最新评论