vue3中ref和reactive的用法,区别和优缺点,以及使用场景

写在前头:
reactive定义的数据只能修改里面的属性,不能将整个数据替换,实在要替换请使用
 

			Object.assign(obj1, obj2);

举个例子
这种写法无法直接改变obj1

let obj1 = reactive({name: '猫',age: '2',
});obj1 = {name: '猪',age: '2',
}

正确的写法
 

let obj1 = reactive({name: '猫',age: '2',
});
Object.assign(obj1, {name: '猪',age: '2',});

或者逐个更改属性
 

let obj1 = reactive({name: '猫',age: '2',
});
obj1.name = '狗'obj1.age = '3'

言归正传:

Vue 3 中,refreactive 是管理响应式数据的两种主要方式。它们的使用场景、工作原理以及各自的优缺点有所不同。以下是它们的用法、区别、优缺点及推荐使用场景的总结。

1. ref 用法

ref 用于定义基本类型或复杂类型的响应式数据。它适合处理基本数据类型(如数字、字符串、布尔值),也可用于对象和数组。

用法示例
import { ref } from 'vue';export default {setup() {const count = ref(0); // 基本数据类型const name = ref('Vue3'); // 字符串const user = ref({ name: 'Alice', age: 25 }); // 对象const increment = () => {count.value++;  // 通过 .value 访问或修改 ref 包裹的值};return { count, name, user, increment };}
};
优点
  • 适合基本数据类型:对于简单的数据类型(如数字、字符串、布尔值),ref 是最佳选择。
  • 可以封装任何类型的数据:不仅限于基本类型,还可以封装对象、数组等复杂类型。
  • 引用式包装:即便是对象或数组,在使用 .value 时也能获取和修改它们的内容。
缺点
  • 需要通过 .value 访问:必须通过 ref.value 的形式访问和更新数据,初学者有时容易忘记或感到不便。
使用场景
  • 简单的原始数据类型:数字、字符串、布尔值等。
  • 需要手动包装非响应式对象:比如希望将一个对象显式地封装为响应式对象。
  • HTML元素引用:通过 ref 还能获取 DOM 元素的引用,比如在模板中操作具体的 DOM。

2. reactive 用法

reactive 用于将对象或数组转换为响应式数据。它适合处理复杂数据结构(如对象、数组等)。

用法示例
import { reactive } from 'vue';export default {setup() {const user = reactive({name: 'Alice',age: 25,hobbies: ['reading', 'coding']});const incrementAge = () => {user.age++;  // 直接修改对象属性,无需 .value};return { user, incrementAge };}
};
优点
  • 直观的语法:不需要 .value,可以像操作普通对象一样直接访问和修改属性,写法更加简洁。
  • 深度响应式reactive 会对对象的所有嵌套属性进行深度监听,无需手动处理嵌套数据。
缺点
  • 只能用于对象和数组reactive 不能用于基本数据类型,如数字、字符串等。
  • 不能直接解构reactive 对象不能直接解构,否则解构后的属性将失去响应式能力。
使用场景
  • 复杂的数据结构:适合对对象、数组、嵌套数据进行响应式管理。
  • 更符合面向对象的数据组织:需要管理对象之间的层级和属性关系时,reactive 更加自然。

3. refreactive 的区别

特性refreactive
适用场景基本数据类型、DOM引用、复杂类型封装对象、数组、嵌套数据
访问方式必须通过 .value 来访问和修改值直接通过对象属性访问和修改
响应式行为对于对象或数组,只有包裹的整体是响应式的,内部属性需要手动用 ref深度响应式,对所有嵌套属性进行监听
能否解构ref 可以解构(解构后仍然需 .value解构后失去响应式能力
语法简洁性访问属性时需要使用 .value操作对象时无需额外 .value

4. 优缺点对比

ref 的优缺点
  • 优点
    • 可以用于任何类型(基本数据类型、对象、数组)。
    • DOM 元素引用方便,常用于操作 template 中的元素。
  • 缺点
    • 必须使用 .value 访问和修改数据,稍显冗余。
    • 对于复杂对象或数组,只能将其整体变为响应式,内部属性需要手动处理。
      具体解释:

      在 Vue 3 中,ref 可以将基本数据类型(如数字、字符串)以及复杂类型(如对象、数组)变为响应式。但当我们使用 ref 包装复杂对象或数组时,ref 只能将整个对象或数组视为一个整体变为响应式,如果你需要对该对象的内部属性进行精细的响应式处理,可能需要手动处理内部属性的响应式特性。

      ref 对复杂对象或数组的处理

      当你用 ref 来处理复杂对象(如对象、数组)时,虽然这个复杂对象是响应式的,但在修改对象内部的某些属性时,不会自动追踪响应。这意味着当我们需要对复杂对象的内部属性进行修改和响应式更新时,可能需要手动将这些属性声明为 ref 或者通过 .value 来显式更新。

    • 示例:ref 包裹对象时的响应式行为

      import { ref } from 'vue';export default {setup() {const user = ref({name: 'Alice',age: 25});const updateName = () => {user.value.name = 'Bob';  // 修改 user 对象内部属性};return { user, updateName };}
      };
      

      在上面的示例中,user 是一个对象,并被 ref 包裹。当我们通过 user.value.name = 'Bob' 修改内部属性时,Vue 能够正确追踪到变化,因为我们通过 .value 明确地修改了整个对象的值。

      问题:无法直接响应复杂对象内部的深层嵌套属性

      假如我们有一个更复杂的嵌套对象,直接修改嵌套属性并不会触发响应式更新。这种情况下,需要显式地通过 .valueref 来处理内部嵌套属性。

    • 示例:复杂嵌套对象需要手动处理的情况

      import { ref } from 'vue';export default {setup() {const user = ref({name: 'Alice',details: {age: 25,address: {city: 'New York'}}});const updateCity = () => {user.value.details.address.city = 'Los Angeles'; // 可能无法正确触发响应式更新};return { user, updateCity };}
      };
      

      在这个示例中,我们将 addressref 包裹,这样内部的 city 属性在被修改时,Vue 就能够自动追踪并更新视图。

      总结

    • ref 用于包装复杂对象时,整个对象是响应式的,但对象内部的嵌套属性修改可能不会自动触发响应式更新。
    • 如果需要对复杂对象或数组的内部属性进行精细化的响应式处理,应该手动将这些属性用 ref 包裹,或者通过 .value 来显式更新嵌套属性的值。
    • 这种情况提醒我们在使用 ref 包裹复杂数据时,要意识到它的局限性,并根据需求选择 refreactive 来管理响应式数据。

    • 对于简单数据类型,ref 是最直接和方便的选择;但在处理复杂对象时,特别是对象的嵌套属性时,可能需要更复杂的手动处理。
reactive 的优缺点
  • 优点
    • 语法更加直观简洁,操作时不需要 .value
    • 深度响应式,适合管理嵌套的复杂数据。
  • 缺点
    • 仅限于对象和数组,无法处理基本数据类型。
    • 不能直接解构对象,否则解构后的属性将失去响应式能力。

5. 推荐的使用场景

使用 ref 的场景
  • 处理基本数据类型:如 numberbooleanstring,可以使用 ref 来确保这些类型是响应式的。
  • 简单的 DOM 引用:在 Vue 中通过 ref 访问 DOM 元素或组件实例。
  • 包装单个值:当你需要管理基本数据类型的响应式数据时,ref 是最合适的。
  • 复杂对象需要显式封装为响应式时:如果你希望将一个对象或数组显式地转换为响应式数据,而不使用 reactive 的深度响应式特性。
使用 reactive 的场景
  • 处理复杂对象或数组:当你需要管理包含多个属性的对象或数组时,reactive 是最佳选择,因为它能够自动处理嵌套的属性和深度响应。
  • 需要更自然的对象操作:对于那些需要频繁操作属性的对象,reactive 提供更符合直觉的语法,不需要使用 .value
  • 表单数据或大规模数据操作:当管理用户表单或需要管理复杂的数据结构(如多个嵌套属性对象)时,reactive 更加灵活高效。

6. 组合使用的场景

在一些场景下,你可以同时使用 refreactive,例如你需要处理一个对象的深度响应式属性,但其中的某些属性需要用 ref 封装以实现特定的逻辑。

示例:refreactive 组合使用

import { ref, reactive } from 'vue';export default {setup() {const count = ref(0);  // 处理简单的基本数据类型const user = reactive({ name: 'Alice', age: ref(25) });  // 组合使用,user 是响应式对象,age 使用 ref 单独封装const incrementAge = () => {user.age.value++;  // 需要用 .value 修改 ref 类型的属性};return { count, user, incrementAge };}
};

总结

  • ref:适合处理基本类型(数字、字符串、布尔值等)和需要显式封装的对象/数组。使用 .value 访问和修改。
  • reactive:适合处理复杂对象和数组,并且会对所有嵌套属性进行深度响应式管理,语法上更符合直觉。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/883570.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【AIGC】从CoT到BoT:AGI推理能力提升24%的技术变革如何驱动ChatGPT未来发展

博客主页: [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 💯前言💯迈向AGI的新跨越💯BoT与CoT的技术对比技术原理差异推理性能提升应用范围和通用性从错误中学习的能力总结 💯BoT的工作流程和机制初始化过程生成推…

网上摄影工作室:Spring Boot框架的应用实例

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统,它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等,非常…

Redis——缓存

目录 前言 一、缓存基本概念 1.概念 2.二八定律 二、使用 Redis 作为缓存 三、缓存的更新策略 1.定期生成 2.实时生成 四、Redis 内存淘汰机制 1.通用淘汰策略 (1)FIFO (2)LRU (3)LFU &#…

buildroot制作自己的软件包(可以理解为应用程序)

以helloworld为例记录使用步骤 一&#xff1a;书写自己的源程序以及Makefile helloworld.c #include <stdio.h>int main(int argc, char **argv) {printf("hello world\r\n");return 0; }Makefile all: helloworldhelloworld: helloworld.o$(CC) -o hellow…

模型训练识别手写数字(二)

模型训练识别手写数字&#xff08;一&#xff09;使用手写数字图像进行模型测试 一、生成手写数字图像 1. 导入所需库 import cv2 import numpy as np import oscv2用于计算机视觉操作。 numpy用于处理数组和图像数据。 os用于文件和目录操作。 2. 初始化画布 canvas np.z…

Kaggle竞赛——灾难推文分类(Disaster Tweets)

目录 1. 准备工作2. 资源导入3. 数据处理4. 绘制词云图5. 数据可视化5.1 词数和字符数可视化5.2 元特征可视化5.3 类别可视化 6. 词元分析6.1 一元语法统计6.2 多元语法统计 7. 命名实体识别8. 推文主题提取9. 构建模型9.1 数据划分与封装9.2 模型训练与验证 10. 模型评估11. 测…

SQL:Windows下MySQL的安装教程(超详细)

一.系统环境&#xff1a; 操作系统&#xff1a; Windows11&#xff1b; MySQL版本&#xff1a; mysql-community-8.0.40.0&#xff1b; 二.MySQL下载&#xff1a; 访问MySQL 官网下载地址&#xff1a;https://www.mysql.com/&#xff0c;点击DOWNLOADS&#xff1b; 跳转后页…

Maven---依赖管理,项目构建工具

1.Maven安装和配置 1.1设置本地仓库 提前准备好仓库的位置,打开配置文件maven/conf/setting.xml 1.2配置阿里镜像源 在mirrors节点(标签)下添加阿里中央仓库镜像,把原本的镜像源注释掉,不要写在mirrors标签外 <mirror><id>alimaven</id><name>aliy…

6 款超实用的 Coze 插件,让你的智能体开发效率提升 200%

最近我一直在频繁使用 Coze 智能体&#xff0c;帮朋友和客户实现各种定制化需求。 Coze 不仅提供了强大的工作流编排能力和全面的功能节点&#xff0c;还有大量由开发者和平台上传的插件库支持。 对于智能体开发者来说&#xff0c;找到一款合适、好用的插件&#xff0c;真的能…

【实用知识】Spring Boot 优雅捕捉异常的几种姿势

&#x1f449;博主介绍&#xff1a; 博主从事应用安全和大数据领域&#xff0c;有8年研发经验&#xff0c;5年面试官经验&#xff0c;Java技术专家&#xff0c;WEB架构师&#xff0c;阿里云专家博主&#xff0c;华为云云享专家&#xff0c;51CTO 专家博主 ⛪️ 个人社区&#x…

JVM(HotSpot):GC之G1垃圾回收器

文章目录 一、简介二、工作原理三、Young Collection 跨代引用四、大对象问题 一、简介 1、适用场景 同时注重吞吐量&#xff08;Throughput&#xff09;和低延迟&#xff08;Low latency&#xff09;&#xff0c;默认的暂停目标是 200 ms超大堆内存&#xff0c;会将堆划分为…

华为云弹性云服务器无法登录远程操作

遇到的问题&#xff1a; 就是你在创建弹性云服务器的时候选择了没有子网的虚拟私有云&#xff0c; 你属于误删了虚拟私有云的子网&#xff0c;自己没有注意看 如果在华为云创建弹性云服务器时选择的虚拟私有云&#xff08;VPC&#xff09;没有配置子网&#xff0c;那么在尝试远…

【mysql 进阶】2-1. MySQL 服务器介绍

MySQL 服务器简介 通常所说的 MySQL 服务器指的是mysqld程序&#xff0c;当运⾏mysqld后对外提供MySQL 服务&#xff0c;这个专题的内容涵盖了以下关于MySQL 服务器以及相关配置的内容&#xff0c;包括&#xff1a; 服务器⽀持的启动选项。可以在命令⾏和配置⽂件中指定这些选…

嵌入式C语言字符串具体实现

大家好,今天主要给大家分享一下,如何使用C语言进行字符串操作与实现。 第一:字符串相关操作实现 复制函数五个基本要素: 头文件:#include <string.h> 函数原型:strcpy(char dest[],char src[]) -----string copy 功能:把src数组中\0之前的所有字符,连同‘\…

在xml 中 不等式 做转义处理的问题

对于这种要做转义处理&#xff0c;<![CDATA[ < ]]>

讲一讲 kafka 的 ack 的三种机制?

大家好&#xff0c;我是锋哥。今天分享关于【K讲一讲 kafka 的 ack 的三种机制&#xff1f;】面试题&#xff1f;希望对大家有帮助&#xff1b; 讲一讲 kafka 的 ack 的三种机制&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Kafka的消息确认机制&…

【计网】UDP Echo Server与Client实战:从零开始构建简单通信回显程序

目录 前言&#xff1a; 1.实现udpserver类 1.1.创建udp socket 套接字 --- 必须要做的 socket&#xff08;&#xff09;讲解 代码实现&#xff1a;​编辑 代码讲解&#xff1a; 1.2.填充sockaddr_in结构 代码实现&#xff1a; 代码解析&#xff1a; 1.3.bind sockfd和…

Vue2自定义指令及插槽

这里写目录标题 自定义指令基础语法指令的值封装v-loading指令 插槽默认插槽后备内容&#xff08;插槽的默认值&#xff09;具名插槽作用域插槽 自定义指令 自定义指令&#xff1a;自己定义的指令&#xff0c;封装一些dom操作&#xff0c;扩展额外功能 基础语法 全局注册&am…

2024年TI杯E题-三子棋游戏装置方案分享-jdk123团队-第四弹 第二题

往期回顾 前期准备 摄像头bug解决 手搓机械臂 视觉模块的封装 下面是题目部分&#xff1a; 第二问我们继续延续第一问的思路&#xff1a; 将棋子坐标与棋盘上标定的坐标进行绑定。 代码展示&#xff1a; import RPi.GPIO as GPIO import time import cv2 import numpy as…

【Qt】常用控件:按钮类控件

思维导图&#xff1a; 一、Push Button 我们可以使用 QPushButton 表示一个按钮&#xff0c;这也是当前我们最熟悉的一个控件。QPushButton继承于QAbstractButton。这个类是一个抽象类&#xff0c;是按钮的父类。 1.1 常用的属性 属性说明text按钮中的文本icon按钮中的图标ic…