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

Vue3中ref与reactive的区别

在 Vue 3 中,refreactive 是两种不同的响应式数据创建方式,它们的区别和实现方式如下:


一、核心区别

特性refreactive
适用类型基本类型 + 对象类型仅对象类型(对象/数组/Map/Set)
访问方式通过 .value 访问直接访问属性
解构响应性需要 toRefs 保持解构后的响应性直接解构会丢失响应性
深层响应性自动递归代理嵌套对象自动递归代理嵌套对象
模板自动解包支持(模板中无需 .value直接访问属性

二、实现方式

1. ref 的实现
  • 核心机制:通过一个对象包装值(RefImpl 类),利用 getter/setter + Proxy 实现响应式。

  • 源码关键点

class RefImpl<T> {
   private _value: T
 private _rawValue: T // 原始值(避免对象被 reactive 二次代理)
   
   constructor(value: T) {
     this._rawValue = value
     this._value = isObject(value) ? reactive(value) : value
   }
   
   get value() {
     track(this, TrackOpTypes.GET, 'value') // 依赖收集
     return this._value
   }
   
   set value(newVal) {
     if (hasChanged(newVal, this._rawValue)) {
       this._rawValue = newVal
       this._value = isObject(newVal) ? reactive(newVal) : newVal
       trigger(this, TriggerOpTypes.SET, 'value') // 触发更新
     }
   }
 }
  • 特点

    • 对基本类型直接通过 getter/setter 监听。
    • 对对象类型内部使用 reactive 代理。
2. reactive 的实现
  • 核心机制:基于 Proxy 代理对象,拦截 get/set/deleteProperty 等操作。

  • 源码关键点

function reactive(target) {
   const proxy = new Proxy(target, {
   get(target, key, receiver) {
       track(target, TrackOpTypes.GET, key) // 依赖收集
       const res = Reflect.get(target, key, receiver)
       return isObject(res) ? reactive(res) : res // 递归代理嵌套对象
     },
     set(target, key, value, receiver) {
       const oldValue = target[key]
       const result = Reflect.set(target, key, value, receiver)
       if (hasChanged(value, oldValue)) {
         trigger(target, TriggerOpTypes.SET, key) // 触发更新
       }
       return result
     }
   })
   return proxy
 }
  • 特点

    • 通过 Proxy 实现深层响应式。
    • 递归代理嵌套对象(性能优化可通过 shallowReactive 避免)。

三、使用场景

1. 使用 ref 的场景
  • 需要响应式的基本类型值(如 string/number/boolean)。
  • 需要显式控制值的引用(如需要重新赋值整个对象时)。
  • 需要兼容模板自动解包(模板中无需 .value)。
2. 使用 reactive 的场景
  • 需要响应式的复杂对象或数组。
  • 需要保持对象引用不变,仅修改属性。
  • 需要深层响应式(如嵌套对象自动代理)。

四、最佳实践

  1. 优先选择 ref
    对于基本类型或需要频繁重新赋值的对象,使用 ref 更直观。

  2. 复杂对象用 reactive
    当需要处理嵌套结构且不需要重新赋值整个对象时,reactive 更简洁。

  3. 解构时用 toRefs
    解构 reactive 对象时,使用 toRefs 保持响应性:

const state = reactive({ count: 0 })
 const { count } = toRefs(state) // 解构后仍为 Ref 类型

五、底层原理对比

机制refreactive
依赖收集通过 getter 中的 track通过 Proxy.get 中的 track
触发更新通过 setter 中的 trigger通过 Proxy.set 中的 trigger
性能开销基本类型更低,对象类型与 reactive 相同对象类型高效,嵌套对象递归代理

总结

  • ref:更通用的响应式工具,通过 .value 访问,适合基本类型或需要重新赋值的对象。
  • reactive:专为对象设计的响应式工具,适合深层嵌套结构,直接访问属性更简洁。
  • 实现差异ref 通过 RefImpl 类包装值,reactive 通过 Proxy 代理对象。

相关文章:

  • 垃圾回收算法
  • Freertos中空闲钩子函数的使用
  • 坐标变换及视图变换和透视变换(相机透视模型)
  • 机器学习-05-回归算法-python动画展示
  • 远程登录到Linux服务器
  • QVariantList使用详解
  • Spark(3)vi的基本使用
  • cpp中的继承
  • BUU40 [CSCCTF 2019 Qual]FlaskLight1【SSTI】
  • Kronecker分解(K-FAC):让自然梯度在深度学习中飞起来
  • java基础相关-深拷贝与浅拷贝介绍
  • Android Audio实战——音频相关基础概念(附)
  • LangChain教程 - RAG - PDF摘要
  • Ascend NPU 架构 CANN 平台入门学习
  • 如何用HBase轻松管理海量数据?
  • 深入解析:使用Python爬虫获取京东商品详情原数据API接口
  • 一篇文章介绍前端mitt
  • 操作系统之内存管理
  • 基于GWO灰狼优化的BiLSTM双向长短期记忆网络序列预测算法matlab仿真,对比BiLSTM和LSTM
  • chat2db邀请码
  • 手机搭建网站教程视频教程/项目推广网
  • 网站建设的品牌/线上营销手段有哪些
  • 镇江网站建设教程/推广关键词排名方法
  • cms网站搭建好了再怎么做/线上广告推广平台
  • css3网站制作教程/太原互联网推广公司
  • 网站制作公司 重庆/济南专业seo推广公司