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

Vue响应式原理(上)

前言

Vue 实现响应式的原理中有两个最重要的步骤:依赖收集和派发更新。接下来我们将围绕这两点进行完善和优化,以实现响应式功能。

具体实现

基础版依赖收集和派发更新
letprice=5letquantity=2lettotal=0letdep=newSet()leteffect=()=>{total=price*quantity}functiontrack(){dep.add(effect)}functiontrigger(){dep.forEach(effect=>effect())}track()effect()

先来简单解释一下核心概念:我们将使用到响应式变量的函数称为副作用函数 (effect),因为它改变了程序的状态。依赖收集 (Track),即记录下哪些副作用函数正在使用该响应式变量;派发更新 (Trigger),当响应式变量改变时,将所有关联的副作用函数从集合中取出并重新执行。

在代码实现中,我们使用track()函数来进行依赖收集,使用trigger()函数来进行派发更新。

完善收集和查找功能

首先,我们将针对对象类型的变量来设计函数。原始类型变量只需要修改值,而对象类型变量较复杂,所以我们优先解决复杂的类型。

对象型变量具有多个键值对,而每个键值对都可能对应多个副作用函数。要建立精确的响应关系,我们需要一套从“对象” -> “属性” -> “副作用函数集合”的映射结构。这启发了我们使用嵌套的 Map 类型数据来存储这种关系。

// 使用WeakMap的原因// 当target对象在业务逻辑中被销毁,被垃圾回收时,WeakMap会自动清理,避免内存泄漏consttargetMap=newWeakMap()functiontrack(target,key){letdepsMap=targetMap.get(target)if(!depsMap){// depsMap的作用是根据对象的属性名查找对应的依赖集合// 属性名通常是字符串或者Symbol类型,Map能够高效抽离各种类型的键值对映射,且这里属性名不需要弱引用targetMap.set(target,(depsMap=newMap()))}letdep=depsMap.get(key)if(!dep){// dep的作用是存储effect,而一个副作用函数(effect)不应该被重复收集// set可以自动去重,避免重复收集depsMap.set(key,(dep=newSet()))}dep.add(effect)}functiontrigger(target,key){constdepsMap=targetMap.get(target)if(!depsMap)returndep=depsMap.get(key)if(dep){dep.forEach(effect=>effect())}}letproduct={price:5,quantity:3}lettotal=0leteffect=()=>{total=product.price*product.quantity}track(product,'quantity')track(product,'price')effect()

在代码中,我们使用targetMap来存储不同对象的引用,其对应的值是该对象的属性地图depsMap。在depsMap中,我们进一步以属性名为键,对应存储该属性的副作用函数集合depdep本质上是一个 Set,存放着所有依赖该属性的副作用函数。

  • targetMap使用WeakMap类型,是因为当target对象在业务逻辑中被销毁时,WeakMap不会阻止垃圾回收,从而自动清理相关记录,避免内存泄漏。
  • depsMap用于根据对象的属性名查找对应的依赖集合。属性名通常是字符串,Map能够高效建立这种键值对映射。
  • dep使用Set存储effect,是因为同一个副作用函数不应该被重复收集,Set能够自动去重。

以下是官方所给出的模型图。

实现自动更新

在这一阶段,虽然实现了逻辑,但每次修改数据都得手动调用trigger(),这显然不符合 Vue “数据驱动”的自动化体验。我们要做的,是让数据在被读取时自动进行 track,在修改时自动运行 trigger

实现这一功能的核心武器是Proxy 代理对象。Vue 3 舍弃了Object.defineProperty,转而使用Proxy,它可以直接拦截对象的基本操作。

// 1. 核心仓库:用于存储所有对象的依赖consttargetMap=newWeakMap()// 2. 追踪函数:负责把 effect 存入账本functiontrack(target,key){letdepsMap=targetMap.get(target)if(!depsMap){targetMap.set(target,(depsMap=newMap()))}letdep=depsMap.get(key)if(!dep){depsMap.set(key,(dep=newSet()))}// 【重点】直接把当前的副作用函数存进去dep.add(effect)}// 3. 触发函数:负责把账本里的函数翻出来执行functiontrigger(target,key){constdepsMap=targetMap.get(target)if(!depsMap)returnconstdep=depsMap.get(key)if(dep){// 【重点】挨个执行之前存进去的任务dep.forEach(effect=>effect())}}// 4. 响应式转换:将普通对象包装成 Proxyfunctionreactive(target){consthandler={get(target,key,receiver){// 在读取属性时,悄悄进行依赖收集track(target,key)returnReflect.get(target,key,receiver)},set(target,key,value,receiver){letoldValue=target[key]letresult=Reflect.set(target,key,value,receiver)// 在值发生变化时,自动触发更新if(oldValue!==value){trigger(target,key)}returnresult}}returnnewProxy(target,handler)}

当前的逻辑非常精妙:在getset中使用Reflect而不是target[key],是为了确保在对象有继承关系时,this指向依然正确。

自动化的闭环:effect()首次运行 -> 触发 Proxy 的get->track()effect存入 Set -> 未来执行product.price = xx时 -> 触发 Proxy 的set->trigger()从 Set取出effect并运行。更新完成!

http://www.jsqmd.com/news/711689/

相关文章:

  • 2026越秀区灭白蚁品牌TOP5推荐专业团队更可靠:广州上门除白蚁、广州住宅灭白蚁、广州别墅白蚁防治、广州商铺除白蚁选择指南 - 优质品牌商家
  • 给社区宠物店搭建耗材损耗智能成本简易核算模板。
  • 2026年3月:这些有实力的伞齿轮闸阀厂家值得推荐,涡轮料浆阀/伞齿轮料浆阀/伞齿轮蝶阀/涡轮蝶阀,伞齿轮厂商口碑分析 - 品牌推荐师
  • 如何在2026年继续运行Flash内容?CefFlashBrowser完整解决方案
  • MySQL分库分表
  • 局域网隔空打印方案
  • LobeChat镜像详解:如何免费部署你的第一个AI聊天应用
  • 如何快速修复损坏的MP4视频文件:5个简单步骤的神奇免费方案
  • VS Code Copilot Next 面试必问TOP 10:从基础token配置到多环境Workflow编排,现在不看明天就淘汰
  • Qt 2D 绘制系统核心原理深度解析
  • 从零部署自主AI平台Hera:构建具备记忆与行动能力的智能体
  • 光伏清洗车远程监控智慧运维系统方案
  • 操作系统级 AI Agent Harness Engineering 的想象空间
  • 对比QClaw和其他Claw,ToDesk AI凭什么更省额度、回答更详细?亲身体验告诉你
  • 软考高级系统架构设计师备考(二十七):软件工程—系统运行与软件维护
  • Flax与Optax简化JAX深度学习训练流程
  • 设计年终奖两种计税方式,智能对比测算表,帮打工人选少交税方案。
  • WPF/WinForm 也能用 ECharts?快来试试这个开源项目
  • GodotPckTool终极指南:5分钟掌握Godot游戏资源包管理技巧
  • MCP 2026低代码对接安全加固指南:等保2.0三级要求下,5类敏感接口零信任改造实录
  • Flax与Optax:高效实现机器学习训练循环的实践指南
  • 边缘计算部署效率革命:Docker+WASM组合实现“一次构建,全域分发”——基于AWS Wavelength、Azure Edge Zones、华为IEF三平台实测对比
  • AI图像生成质量评估:从指标解析到工程实践
  • 软考高级系统架构设计师备考(二十八):系统架构设计—软件架构基础
  • 康富斯地坪研磨机厂家推荐,优质之选!
  • 用PSIM搞定毕业设计:手把手教你仿真12V转36V直流升压电路(附参数计算与避坑指南)
  • 医疗大模型在放射学报告生成中的挑战与优化策略
  • 2026年国内太空舱厂家实力排行:五家头部企业盘点 - 优质品牌商家
  • 2026年家用电梯安装公司技术实力实测与选型推荐 - 优质品牌商家
  • LeanClaw:本地AI助手运行时架构解析与安全部署实践