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

Vue 3中reactive、ref、watchEffect和watch的底层原理及核心区别解析

以下是Vue 3中reactive、ref、watchEffect和watch的底层原理及核心区别解析,结合实现机制和设计哲学进行深度对比:

🔧 一、reactive 与 ref 的底层原理

1. reactive:基于Proxy的深度代理

• 实现机制:  

  • 使用 Proxy 拦截对象的所有操作(get/set/deleteProperty等),通过 Reflect 操作原始数据。  

  • 依赖收集:在 get 操作中调用 track(target, key) 建立依赖关系;在 set 操作中调用 trigger(target, key) 触发更新。  

  • 深度响应:嵌套对象属性访问时,递归调用 reactive 创建子代理,实现全对象树的响应式。  

  // 简化实现function reactive(target) {return new Proxy(target, {get(target, key) {track(target, key); // 依赖收集return isObject(target[key]) ? reactive(target[key]) : target[key];},set(target, key, value) {Reflect.set(target, key, value);trigger(target, key); // 触发更新return true;}});}


2. ref:基于Getter/Setter的封装

• 实现机制:  

  • 通过 Object.defineProperty 封装 .value 属性,劫持其读写操作。  

  • 基本类型处理:直接劫持 .value 的get/set,触发依赖更新。  

  • 对象类型处理:若值为对象,内部自动调用 reactive 转换为响应式对象。  

  • 依赖管理:依赖收集和触发均在 .value 属性上完成,与 reactive 解耦。  
// 简化实现

  function ref(value) {return {get value() {track(this, 'value'); // 依赖收集return isObject(value) ? reactive(value) : value;},set value(newVal) {value = newVal;trigger(this, 'value'); // 触发更新}};}

  

3. 核心区别对比

⚙️ 二、watchEffect 与 watch 的底层原理

1. watchEffect:自动依赖收集的副作用

• 实现机制:  

  • 立即执行:初始化时同步执行回调函数,在 effect 系统中将当前回调设为 activeEffect。  

  • 依赖收集:执行过程中访问的响应式属性(如 ref.value 或 reactive 属性),自动触发其 track 逻辑,建立依赖关系。  

  • 重新执行:依赖变化时,调度器将回调加入微任务队列异步执行(默认 flush: 'pre')。  

  function watchEffect(fn) {const effect = () => {activeEffect = fn; // 设为当前激活的副作用fn(); // 执行并收集依赖};effect();}


2. watch:显式指定源的精确监听

• 实现机制:  

  • 惰性执行:默认不立即执行,仅当监听源变化时触发回调(除非配置 immediate: true)。  

  • 依赖来源:显式指定监听源(ref、reactive属性、getter函数或数组),内部调用 track 绑定特定属性。  

  • 新旧值比对:存储旧值快照,回调中可对比变化(对象类型需 deep: true 深度监听)。  

  function watch(source, cb) {let oldValue;if (isRef(source)) track(source, 'value'); // 监听refelse if (isReactive(source)) traverse(source); // 深度遍历reactiveconst trigger = () => {const newValue = getSourceValue(source);cb(newValue, oldValue); // 传递新旧值oldValue = newValue;};// 依赖变化时触发trigger}

3. 核心区别对比

🧠 三、设计哲学与最佳实践

1. reactive vs ref 选择  
• reactive:管理复杂嵌套状态(如表单对象、配置树),避免频繁整体替换。  

   • ref:处理基本类型或需替换的独立值(如计数器、API响应数据),配合 toRefs 解构响应性。  

2. watchEffect vs watch 选择  
• watchEffect:适用于依赖动态变化的逻辑(如组合多个状态计算),简化代码。  

   • watch:需要精确控制监听源或对比变化前后值的场景(如撤销操作、深度监听对象)。  

3. 性能陷阱规避  
• 避免在 watchEffect 中使用条件分支依赖,防止意外收集。  

   • reactive 嵌套过深时,用 shallowReactive 优化。  

   • 组件卸载时调用返回的停止函数,防止内存泄漏。  

💎 总结

• reactive:Proxy 深度代理,为复杂对象设计。  

• ref:getter/setter 封装,灵活支持基本类型和对象替换。  

• watchEffect:自动依赖收集,适合副作用逻辑。  

• watch:显式监听,提供精确控制和值比对能力。  

通过理解底层机制(如 Proxy 代理与 getter/setter 劫持),开发者可精准匹配工具与场景。例如:操作嵌套表单用 reactive + watch 深度监听;独立状态管理用 ref + watchEffect 自动响应。

----

http://www.lryc.cn/news/594177.html

相关文章:

  • SQL189 牛客直播各科目同时在线人数
  • SQL 调优第一步:EXPLAIN 关键字全解析
  • [Java恶补day44] 整理模板·考点七【二叉树】
  • Docker Desktop 入门教程(Windows macOS)
  • HTTP 进化史:从 1.0 到 3.0
  • The FastMCP Client
  • 你的created_time字段,用DATETIME还是TIMESTAMP?
  • Python自动化测试项目实战
  • Python 模块与包导入 基础讲解
  • Haproxy算法精简化理解及企业级高功能实战
  • 如何在看板中体现任务依赖关系
  • Windows CMD(命令提示符)中最常用的命令汇总和实战示例
  • 让黑窗口变彩色:C++控制台颜色修改指南
  • 30天打牢数模基础-SVM讲解
  • Linux操作系统从入门到实战(十一)回车换行问题与用户缓冲区问题
  • 内网后渗透攻击过程(实验环境)--3、横向攻击
  • dify创建OCR工作流
  • java抗疫物质管理系统设计和实现
  • 多人在线场景下Three.js同步机制设计:延迟补偿、状态插值的工程实践
  • 07_图像容器Mat_详解
  • 元学习算法的数学本质:从MAML到Reptile的理论统一与深度分析
  • maven构建Could not transfer artifact失败原因
  • 红宝书单词学习笔记 list 51-75
  • Word for mac使用宏
  • Function Callingの进化路:源起篇
  • Node.js Express keep-alive 超时时间设置
  • 基于Pytorch的人脸识别程序
  • 【JS逆向基础】数据库之redis
  • 华为开源自研AI框架昇思MindSpore应用案例:基于ERNIE模型实现对话情绪识别
  • 对于stm32RCT6的外部中断