尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
《Vue3 从入门到大神33篇》Vue3 源码详解(三):响应式核心思想——从 Object.defineProperty 到 Proxy
本篇关键词响应式本质、Proxy、依赖收集、effect、track、trigger难度等级⭐⭐⭐⭐☆偏底层但全程带 Demo工程价值读懂这一篇你能手写简易状态管理库、精准定位响应式 Bug、面试秒杀 90% 候选人。一、开篇为什么 Vue3 要抛弃 Object.defineProperty如果你用过 Vue2一定写过这样的代码data() { return { list: [1, 2, 3] } }然后你发现this.list[0] 99 // ❌ 不触发更新 this.list.length 0 // ❌ 不触发更新 delete this.obj.a // ❌ 不触发更新Vue2 的解决方案是set、delete、重写数组方法。这些不是“特性”而是补丁。Vue2 响应式的本质缺陷Object.defineProperty只能做到✅ 劫持已有属性❌ 无法监听新增 / 删除属性❌ 无法监听数组索引 / length❌ 需要递归遍历对象性能差结论Vue2 的响应式是“后天修补出来的”。二、Vue3 的解法Proxy 带来的降维打击Vue3 使用Proxy一句话概括其优势Proxy 是对整个对象的拦截而不是对属性的拦截。Proxy 最直观的 Demo先感性理解const obj { count: 0 } const proxy new Proxy(obj, { get(target, key, receiver) { console.log(读取 ${key}) return Reflect.get(target, key, receiver) }, set(target, key, value, receiver) { console.log(修改 ${key} ${value}) return Reflect.set(target, key, value, receiver) } }) proxy.count // 读取 count proxy.count 1 // 修改 count 1✅ 新增属性能拦截✅ 删除属性能拦截✅ 数组索引能拦截✅ 嵌套对象懒代理后面讲三、响应式系统的灵魂三问源码级思维在阅读 Vue3 响应式源码前必须先回答三个问题谁用了这个数据依赖收集数据变了通知谁依赖触发如何避免无限循环调度控制Vue3 的答案非常优雅概念对应源码依赖收集track()触发更新trigger()副作用函数effect()四、手写 Mini ReactiveVIP 核心环节不先写 Demo直接读源码 劝退。下面我们用不到 30 行代码实现一个最简响应式系统。Step 1存储依赖的数据结构// 存储所有副作用 const targetMap new WeakMap() // 当前正在执行的 effect let activeEffect null设计说明WeakMaptarget, Mapkey, Seteffect为什么用WeakMap防止内存泄漏为什么用Set防止重复收集Step 2track —— 依赖收集function track(target, key) { if (!activeEffect) return let depsMap targetMap.get(target) if (!depsMap) { targetMap.set(target, (depsMap new Map())) } let dep depsMap.get(key) if (!dep) { depsMap.set(key, (dep new Set())) } dep.add(activeEffect) }一句话解释把“当前正在执行的副作用函数”存到“目标对象的指定属性”下。Step 3trigger —— 触发更新function trigger(target, key) { const depsMap targetMap.get(target) if (!depsMap) return const dep depsMap.get(key) if (dep) { dep.forEach(effect effect()) } }一句话解释找到“目标对象指定属性的所有副作用”挨个执行。Step 4effect —— 副作用容器function effect(fn) { activeEffect fn fn() // 执行一次触发 track activeEffect null }关键点执行fn()时内部读取响应式数据触发get→ 调用track完成依赖收集Step 5reactive —— 创建响应式对象function reactive(obj) { return new Proxy(obj, { get(target, key, receiver) { const result Reflect.get(target, key, receiver) track(target, key) return result }, set(target, key, value, receiver) { const result Reflect.set(target, key, value, receiver) trigger(target, key) return result } }) }Step 6完整 Demo 跑起来 const state reactive({ count: 0 }) effect(() { console.log(count , state.count) }) state.count // 控制台自动打印count 1 state.count 5 // 控制台自动打印count 5✅恭喜你你已经理解了 Vue3 响应式的 80% 核心逻辑。五、对照 Vue3 源码你写的就是简化版源码你现在写的代码本质上就是packages/reactivity/src/ ├── effect.ts ← effect / track / trigger ├── reactive.ts ← reactive() └── baseHandlers.ts ← Proxy handlers源码中的关键对应关系手写Vue3 源码activeEffecteffectStacktrack()track()trigger()trigger()depsDep类型区别只是源码多了调度器、递归代理、边界处理。六、工程视角为什么这样设计VIP 重点1️⃣ 为什么用 WeakMapWeakMap → key 必须是对象好处对象销毁 → 键值自动回收避免手动清理依赖Vue2 的痛点2️⃣ 为什么 effect 要支持嵌套effect(() { effect(() { console.log(state.count) }) })Vue3 使用effectStack​ 解决effectStack.push(effect) activeEffect effect3️⃣ 为什么需要调度器Scheduler试想state.count state.count你不希望触发两次更新。Vue3 通过queueJobnextTickflushPostFlushCbs实现异步批量更新。下一篇详细讲七、调试实战在源码中验证你的理解回到第二篇搭建的环境在以下位置打断点packages/reactivity/src/effect.ts重点关注track()何时被调用trigger()如何遍历depactiveEffect的变化过程你会发现源码逻辑和你手写的 Mini Reactive 几乎一致。八、面试高频追问收藏级Proxy 一定能监听到所有变化吗不能。Map、Set需要单独处理mutableHandlersvscollectionHandlersVue3 为什么还要 refProxy 无法代理基本类型ref本质是{ value }对象的语法糖。track 和 trigger 一定是同步的吗不一定。计算属性、watch、组件更新都可能被调度延迟。九、本篇总结✅ Vue3 响应式 Proxy WeakMap Effect✅ 核心流程读取收集 → 修改触发​✅ 手写 Mini Reactive 是读源码的最短路径✅ 工程中理解调度器、嵌套 effect、内存管理一句话升华Vue3 的响应式不是“魔法”而是一个设计极其精巧的观察者模式 代理模式组合。十、下一篇预告《Vue3 源码详解四reactive 与 ref 源码解析搞懂响应式对象创建过程》
RELATED

相关推荐

从 `hello.c` 到 ELF:亲手走一遍 GCC 编译、汇编与链接全过程

从 `hello.c` 到 ELF:亲手走一遍 GCC 编译、汇编与链接全过程

平时编译 C 程序,我们往往只写一条命令: gcc hello.c -o hello几秒之后,可执行文件就生成了。 但这条命令背后到底发生了什么?头文件去了哪里?.o 为什么不能直接运行?printf 的实现什么时候进入程序&#x…

📅 2026/10/23 23:35:08
深度解析Grammarly Premium Cookie自动化采集架构与三级验证机制

深度解析Grammarly Premium Cookie自动化采集架构与三级验证机制

深度解析Grammarly Premium Cookie自动化采集架构与三级验证机制 【免费下载链接】autosearch-grammarly-premium-cookie 免费白嫖使用Grammarly Premium高级版 项目地址: https://gitcode.com/gh_mirrors/au/autosearch-grammarly-premium-cookie Grammarly Premium高级…

📅 2026/11/4 5:03:17
cann/asc-devkit printf调试接口

cann/asc-devkit printf调试接口

printf 【免费下载链接】asc-devkit 本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。 项目地址: https://gitcode.com/can…

📅 2026/9/6 5:03:44
MORE NEWS

更多资讯

📰

睢县 低压电工证实操考试考什么

睢县低压电工证上岗必备,学历不高也能考吗? 你是不是也担心自己学历不够,根本报不上睢县低压电工证?别慌,这证其实和学历关系不大,只要你满足基本条件,照样能考。别再被“文凭门槛”绊住脚步,低压电工证是很多岗位的 上岗必备…

📰

睢县 低压电工证模拟考试题库

睢县低压电工证怎么考?官方回应帮你避开报名坑 你是不是也正愁不知道睢县低压电工证怎么报名?怕被那些中介套路,花钱还拿不到证?别急,今天我就从一个干了10年应急管理行业的老手角度,带你一步步搞清楚怎么在睢县考低压电工证,避免踩坑!…

📰

涵江考电工证多少钱?怕考不过白交培训费?这些细节必须知道

涵江考电工证多少钱?怕考不过白交培训费?这些细节必须知道 怕考不过白交培训费?这是很多想考电工证的朋友最担心的事。特别是现在市面上培训机构五花八门,价格参差不齐,不少人担心花了钱最后还是拿不到证。今天咱们就来聊聊 涵江考电工证…

📰

西安低压电工证考证含金量高吗?怕考不过白交培训费的看过来

西安低压电工证考证含金量高吗?怕考不过白交培训费的看过来 怕考不过白交培训费?别急,西安低压电工证考证含金量高不高,得看你是怎么准备的。很多人以为只要找培训机构报个名就能拿证,结果一考试就挂,钱花了,时间也浪费了。其实,低压电工证考试并不是…

📰

英州哪里可以考电工证官方回应证书过期了不知道怎么复审延期

英州哪里可以考电工证官方回应证书过期了不知道怎么复审延期 证书过期了不知道怎么复审延期,这是很多电工从业者最头疼的问题之一,尤其是英州地区的朋友,常常因为不了解流程和官方政策,导致证书失效影响工作。今天我们就来聊聊【英州哪里可以考电工证】的…

📰

电工证证件从哪里查询 一位焦作学员的真实经历告诉你怎么避坑

电工证证件从哪里查询 一位焦作学员的真实经历告诉你怎么避坑 不知道去哪报名怕被中介坑?这是很多想考电工证的人最真实的感受。尤其是像我这样从零开始准备考试的人,一开始对流程、机构、考试内容都一无所知,结果差点被一些不靠谱的培训机构骗了报名费,…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬