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

vue3中 ref() 和 reactive() 的区别

在 Vue 3 中,ref()reactive() 是两种核心的响应式 API,用于创建和管理响应式数据。它们各有适用场景,理解它们的区别和用法对开发至关重要。以下是详细对比和示例:


1. ref() 的用法

1.1 基本概念
  • ref() 用于创建一个响应式引用,适用于基本数据类型(如 numberstringboolean)和复杂数据类型(如对象、数组)。
  • 返回值是一个带有 .value 属性的对象,即使传入的是复杂数据类型,也需通过 .value 访问或修改值。
1.2 使用场景
  • 需要直接操作基本数据类型(如计数器、布尔值)。
  • 需要将整个对象或数组作为单一值管理(如动态替换整个对象)。
  • 需要与 Vue 2 的 this.$data 行为兼容。
1.3 示例
import { ref } from 'vue';// 基本数据类型
const count = ref(0); // 创建一个响应式整数
console.log(count.value); // 读取值:0
count.value++; // 修改值:1// 复杂数据类型
const user = ref({ name: 'Alice', age: 20 }); // 创建一个响应式对象
console.log(user.value.name); // 读取对象属性
user.value.age = 21; // 修改对象属性// 数组
const list = ref([1, 2, 3]); // 创建一个响应式数组
list.value.push(4); // 修改数组
1.4 模板中使用

在模板中无需 .value,Vue 会自动解包:

<template><div>{{ count }}</div> <!-- 自动显示 count.value --><div>{{ user.name }}</div> <!-- 自动显示 user.value.name -->
</template>

2. reactive() 的用法

2.1 基本概念
  • reactive() 用于创建一个响应式对象,适用于复杂数据类型(对象或数组)。
  • 返回值是一个代理对象(Proxy),直接访问或修改属性即可触发响应式更新,无需 .value
2.2 使用场景
  • 管理嵌套复杂的对象或数组(如表单数据、配置对象)。
  • 需要直接操作对象属性而不想用 .value
2.3 示例
import { reactive } from 'vue';// 对象
const user = reactive({ name: 'Bob', age: 25 }); // 创建响应式对象
console.log(user.name); // 直接访问属性
user.age = 26; // 直接修改属性// 数组
const list = reactive([1, 2, 3]); // 创建响应式数组
list.push(4); // 直接修改数组
2.4 模板中使用

直接绑定属性名:

<template><div>{{ user.name }}</div> <!-- 直接访问 user.name --><div>{{ list[0] }}</div> <!-- 直接访问数组元素 -->
</template>

3. ref() 与 reactive() 的区别

特性ref()reactive()
适用数据类型基本类型、对象、数组仅对象或数组
返回值类型带 .value 的对象代理对象(Proxy)
访问/修改方式refValue.valuereactiveObject.property
模板中使用自动解包,无需 .value直接访问属性
深度响应式是(若传入对象,内部会调用 reactive是(嵌套对象/数组自动代理)
替换整个对象可以(ref.value = newObject不推荐(直接替换会丢失响应式)
性能优化基础类型更轻量复杂对象更高效

4. 综合示例对比

4.1 场景:计数器
  • ref()
    const count = ref(0);
    function increment() {count.value++;
    }
  • reactive()
    const state = reactive({ count: 0 });
    function increment() {state.count++;
    }
4.2 场景:表单数据
  • ref()
    const formData = ref({ name: '', email: '' });
    formData.value.name = 'Alice'; // 修改需 .value
  • reactive()
    const formData = reactive({ name: '', email: '' });
    formData.name = 'Alice'; // 修改无需 .value
4.3 场景:动态替换对象
  • ref()
    const user = ref({ name: 'Alice' });
    user.value = { name: 'Bob' }; // 安全替换整个对象
  • reactive()
    const user = reactive({ name: 'Alice' });
    user = reactive({ name: 'Bob' }); // 错误!不能直接替换 reactive 对象

5. 企业级最佳实践

  1. 选择原则

    • 基础类型 → ref()
    • 对象/数组 → reactive()
    • 需要替换整个对象 → ref()
    • 嵌套复杂结构 → reactive()
  2. 避免陷阱

    • 解构响应式对象:使用 toRefs() 保持响应式。
      const state = reactive({ count: 0, name: 'Alice' });
      const { count, name } = toRefs(state); // 保持响应式
    • 大型静态数据:避免用 reactive() 包裹,改用 markRaw() 标记非响应式。
  3. 性能优化

    • 高频更新基础类型(如动画帧数) → 优先 ref()
    • 大型嵌套对象 → 优先 reactive()

6. 总结

  • ref():适合简单值或需要替换整个对象的场景,使用 .value 访问。
  • reactive():适合复杂嵌套对象,直接访问属性,代码更简洁。
  • 核心区别ref() 是 reactive() 的“包装器”,在处理对象时内部会调用 reactive(),但需要通过 .value 操作。

根据实际需求选择合适的 API,可以提升代码的可维护性和性能。


文章转载自:

http://wTjTDPqp.phxdc.cn
http://29olK09z.phxdc.cn
http://gikC3Vr1.phxdc.cn
http://XhdyR7h6.phxdc.cn
http://PxhgD8dg.phxdc.cn
http://XIPW6Iwi.phxdc.cn
http://IGV0MqbY.phxdc.cn
http://ieFdyYIG.phxdc.cn
http://hCIhDVzr.phxdc.cn
http://VxkUJwbt.phxdc.cn
http://Ob7nIu1N.phxdc.cn
http://FvFctY5v.phxdc.cn
http://shvLUPmk.phxdc.cn
http://vFHZ5pB0.phxdc.cn
http://zGPjXSZ0.phxdc.cn
http://wwDaeIuC.phxdc.cn
http://qn53NCac.phxdc.cn
http://a46XAPir.phxdc.cn
http://DnqEO24u.phxdc.cn
http://wUrT6D3a.phxdc.cn
http://o9Xg8DHi.phxdc.cn
http://UMpRjTTA.phxdc.cn
http://tVi26W3t.phxdc.cn
http://YeowSizU.phxdc.cn
http://aopKx7G8.phxdc.cn
http://UOm1Q9FL.phxdc.cn
http://4QSXxv6a.phxdc.cn
http://XgX0eWxb.phxdc.cn
http://S7gtRlcj.phxdc.cn
http://2GLDxxli.phxdc.cn
http://www.dtcms.com/a/374508.html

相关文章:

  • # Redis C++ 实现笔记(H篇)
  • 【GD32】存储器架构介绍
  • 3.HTTP/HTTPS:报文格式、方法、状态码、缓存、SSLTLS握手
  • 【Leetcode hot 100】146.LRU缓存
  • Android 图片 OOM 防护机制设计:大图加载、内存复用与多级缓存
  • Kubernetes 实战练习指南
  • 滴滴二面准备(一)
  • 机器人控制器开发(部署——软件打包备份更新)
  • 企业级CI/CD全流程实战指南
  • VMware与cpolar:虚拟机跨网络协作的无缝解决方案
  • 【深度学习计算机视觉】03:目标检测和边界框
  • IP 访问限制选型指南(含实现示例与存储策略)
  • 思瑞浦 3PEAK ASN:高效率低成本多路音频传输方案,车规级音频芯片国产突破
  • c primer plus 第四章复习题和练习题
  • ES+MySQL实时搜索架构实战解析
  • ​人脸表情识别检测数据集​:近4k图像,8类,yolo标注
  • 【智能协同云图库】基于统一接口架构构建多维度分析功能、结合 ECharts 可视化与权限校验实现用户 / 管理员图库统计、通过 SQL 优化与流式处理提升数据
  • Linux使用-MySQL的使用
  • Linux grep 命令使用说明
  • 双引擎驱动!中新赛克AI安全方案入选网安创新大赛优胜榜单
  • Day42 PHP(mysql注入、跨库读取)
  • 开源 C++ QT Widget 开发(十四)多媒体--录音机
  • 小白成长之路-jenkins使用pipline部署
  • Elasticsearch面试精讲 Day 15:索引别名与零停机更新
  • vscode中使用git、githup的基操
  • Elasticsearch面试精讲 Day 12:数据建模与字段类型选择
  • 【Visual Studio 2017 和 2019下载】
  • 领码方案·AI狂潮:3天极速塑造高可用电商核心架构——从需求到上线,用智能驱动架构革新,打造可扩展、可维护、可复用的电商系统新范式
  • SpringCloud gateway配置predicates的匹配规则
  • Win系统下配置PCL库第一步之下载Visual Studio和Qt 5.15.2(超详细)