返回列表 发布新帖
查看: 15|回复: 0

ref和reactive底层原理的区别

发表于 昨天 16:01 | 查看全部 |阅读模式

这里或许是互联网从业者的最后一片净土,随客社区期待您的加入!

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 zzz 于 2025-7-18 16:12 编辑

refreactive都是构建响应式数据模型的两大核心工具,分别服务于不同的场景并具有独特的使用方式与底层实现机制。

数据类型支持
  ref:支持基本类型(如字符串、数字、布尔值)和对象类型,内部会自动将对象类型转换为reactive实现响应式代理。
  reactive:仅支持对象、数组、Map/Set等复杂类型,通过Proxy代理实现深度响应式追踪。

响应式实现机制
  ref:通过封装对象的.value属性实现响应式,对基本类型使用Object.defineProperty劫持数据,对象类型则调用reactive转换为代理。
  它的实现依赖于RefImpl类,并通过track和trigger机制 实现依赖收集和更新触发。
  1. //源码分析
  2. class RefImpl<T> {
  3.   private _value: T
  4.   public readonly __v_isRef = true

  5.   constructor(private _rawValue: T, public readonly _shallow = false) {
  6.     // 将原始值转换为响应式值
  7.     this._value = _shallow ? _rawValue : convert(_rawValue)
  8.   }

  9.   get value() {
  10.     // 依赖收集
  11.     track(toRaw(this), TrackOpTypes.GET, 'value')
  12.     return this._value
  13.   }

  14.   set value(newVal) {
  15.     // 检查值是否发生变化
  16.     if (hasChanged(toRaw(newVal), this._rawValue)) {
  17.       this._rawValue = newVal
  18.       // 更新值并转换为响应式
  19.       this._value = this._shallow ? newVal : convert(newVal)
  20.       // 触发更新
  21.       trigger(toRaw(this), TriggerOpTypes.SET, 'value', newVal)
  22.     }
  23.   }
  24. }

  25. function ref(value) {
  26.   return createRef(value)
  27. }

  28. function createRef(rawValue, shallow = false) {
  29.   if (isRef(rawValue)) {
  30.     return rawValue
  31.   }
  32.   return new RefImpl(rawValue, shallow)
  33. }
  34. // RefImpl类:ref的核心实现类,通过get和set访问器拦截对.value的访问和修改。
  35. //   get:在访问.value时,调用track进行依赖收集。
  36. //   set:在修改.value时,调用trigger触发更新。
  37. // convert函数:将原始值转换为响应式值。如果原始值是对象,则调用reactive将其转换为响应式对象。
  38. // track和trigger:Vue 3的响应式系统的核心机制,分别用于依赖收集和更新触发。
复制代码
reactive:Proxy拦截对象的增删改查操作,结合Reflect操作原始数据,实现深层响应式追踪。
  1. function reactive(target) {
  2.   if (target && target.__v_isReadonly) {
  3.     return target
  4.   }
  5.   return createReactiveObject(
  6.     target,
  7.     false,
  8.     mutableHandlers,
  9.     mutableCollectionHandlers
  10.   )
  11. }

  12. function createReactiveObject(
  13.   target,
  14.   isReadonly,
  15.   baseHandlers,
  16.   collectionHandlers
  17. ) {
  18.   if (!isObject(target)) {
  19.     return target
  20.   }
  21.   // 创建Proxy代理
  22.   const proxy = new Proxy(target, baseHandlers)
  23.   return proxy
  24. }
  25. // Proxy:reactive通过Proxy代理目标对象,拦截对对象属性的访问和修改。
  26. //   get:在访问属性时,调用track进行依赖收集。
  27. //   set:在修改属性时,调用trigger触发更新。
  28. // mutableHandlers:Proxy的处理器对象,定义了get、set、deleteProperty等拦截器。
  29. // createReactiveObject函数:负责创建Proxy代理对象,并处理边界情况(如只读对象、非对象值等)。
复制代码

适应场景
‌  ref:适合简单数据、需跨组件传递的独立变量或需替换整个对象的场景。
‌  reactive:适合复杂嵌套对象、数组或需深度响应式追踪的场景。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Copyright © 2001-2025 Suike Tech All Rights Reserved. 随客交流社区 (备案号:津ICP备19010126号) |Processed in 0.126544 second(s), 9 queries , Gzip On, MemCached On.
关灯 在本版发帖返回顶部
快速回复 返回顶部 返回列表