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

【Vue3 知识第七讲】reactive、shallowReactive、toRef、toRefs 等系列方法应用与对比

文章目录

    • 一、reactive()
    • 二、readonly()
    • 三、shallowReactive()
    • 四、shallowReadonly()
    • 五、isReactive() 和 isReadonly()
    • 六、toRef()
    • 七、toRefs()
    • 八、toRaw()
    • 九、ref、toRef、toRefs 异同点

一、reactive()

reactive() 函数用于返回一个对象的响应式代理。与 ref() 函数定义响应式数据的异同点如下:

数字化管理平台
Vue3+Vite+VueRouter+Pinia+Axios+ElementPlus
权限系统-商城
个人博客地址

  • ref 函数和 reactive 函数都是用来定义响应式数据的。

  • ref 函数更适合定义基本数据类型(可接收基本数据类型和对象)

    • 函数参数可以是基本数据类型,也可以接受对象类型

    • 如果参数是对象类型时,其实底层的本质还是 reactive,系统会自动给 ref 传入的值进行转换

      ref(1) -> reactive({value:1})
      // ref函数只能操作浅层次的数据,把基本数据类型当作自己的属性值;深层次依赖于reactive
      
    • 在 template 中访问,系统会自动添加 .value 。在 js 中需要手动 .value 进行访问

      import { ref } from 'vue'// 为基本数据类型添加响应式状态
      const name = ref('Neo')// 为复杂数据类型添加响应式状态
      const state = ref({count: 0
      })// 打印name的值
      console.log(name.value)
      // 打印count的值
      console.log(state.value.count)
      
    • ref 响应式原理是依赖于Object.defineProperty()get()set()

  • reactive 函数更适合定义复杂的数据类型(json/arr/obj/map/set)

    • 它的响应式是更加‘深层次’的(会影响对象内部所有嵌套的属性,所有的数据都是响应式的),底层本质是将传入的数据包装成一个 JavaScript Proxy,其行为表现与一般对象相似。不同之处在于 Vue 能够跟踪对响应式对象属性的访问与更改操作。因此不等于源对象,建议只使用响应式代理,避免使用原始对象。

      import { reactive } from 'vue'let list = reactive([])
      const addData = () => {setTimeout(() => {let arr = ['banana','orange','peal']list.push(...arr)console.log(list)},1000)
      }
      
    • 参数必须是对象或者数组,如果要让对象的某个元素实现响应式时比较麻烦。需要使用 toRefs 函数处理

      import { reactive, toRefs } from 'vue'// 通过 reactive 定义响应式数据
      const state = reactive({// 定义每一个表单控件的配置项:type类型、label文本、prop绑定字段 等信息items: [{label: "用户名",prop: "name",inputwidth: "100%",}, {password: true,label: "密码",prop: "pwd",inputwidth: "100%",rules: [{ required: true, message: "请输入密码", trigger: 'blur' }]}, {label: "手机号",prop: "phone",inputwidth: "100%",required: true,validateType: "phone"}],// 定义每一个表单绑定字段对应的信息(form表单数据信息)formData: {name: "",pwd: "",phone: ""},// form 元素配置信息options: {size: "small",formWidth: "35%",//表单占父元素的宽度labelWidth: "80px",//标签的长度},
      })// 通过 toRefs 获取 reactive 中的每一项属性的引用(js中调用使用 .value,template 中直接使用自动解析)
      const { items, formData, options } = toRefs(state);console.log(items,options)
      
    • 获取数据值的时候直接获取,不需要加.value

      import { reactive } from 'vue'// 响应式状态
      const state = reactive({count: 0
      })// 打印count的值
      console.log(state.count)
      

二、readonly()

readonly() 函数接受一个对象 (不论是响应式还是普通的) 或是一个 ref,返回一个原值的只读代理。本身不能去修改值,但受原始对象改变的影响。

import { readonly } from "vue"let obj = reactive({name:"Jack"})let readObj = readonly(obj)const change = () => {// 不能直接修改只读属性// readObj.name = "Lucy";// 受原始对象改变的影响obj.name = "David";console.log(obj,readObj);
}

只读代理是深层的:对任何嵌套属性的访问都将是只读的。它的 ref 解包行为与 reactive() 相同,但解包得到的值是只读的。

三、shallowReactive()

reactive() 的浅层作用形式。和 reactive() 不同,这里没有深层级的转换:一个浅层响应式对象里只有根级别的属性是响应式的。属性的值会被原样存储和暴露,这也意味着值为 ref 的属性不会被自动解包了。

import { reactive,shallowReactive } from "vue";const stu = reactive({name:"Jack"})const obj = shallowReactive({foo:{bar:{num:1}}
})const change = () => {// reactive() 作用是深层次的,和shallowReactive() 一起使用时,会影响其数据变化stu.name = "David"// shallowReactive() 作用是浅层的,只能修改第一层的数据。深层次数据无法修改。但是会受reactive数据修改的影响。obj.foo.bar.num = 1000;console.log(obj)
}

四、shallowReadonly()

readonly() 的浅层作用形式。和 readonly() 不同,这里没有深层级的转换:只有根层级的属性变为了只读。属性的值都会被原样存储和暴露,这也意味着值为 ref 的属性不会被自动解包了。同样会受原始对象数据改变的影响。

const state = shallowReadonly({foo: 1,nested: {bar: 2}
})// 更改状态自身的属性会失败
state.foo++// ...但可以更改下层嵌套对象
isReadonly(state.nested) // false// 这是可以通过的
state.nested.bar++

五、isReactive() 和 isReadonly()

  • isReactive() 函数检查一个对象是否是由 reactive()shallowReactive() 创建的代理。
  • isReadonly() 函数检查传入的值是否为只读对象。只读对象的属性可以更改,但他们不能通过传入的对象直接赋值。

数字化管理平台
Vue3+Vite+VueRouter+Pinia+Axios+ElementPlus
权限系统-商城
个人博客地址

六、toRef()

toRef() 函数基于响应式对象上的一个属性,创建一个对应的 ref。这样创建的 ref 与其源属性保持同步:改变源属性的值将更新 ref 的值,反之亦然。

toRef() 函数一次仅能设置一个数据,接收两个参数,第一个参数是哪个对象,第二个参数是对象的哪个属性。

<script setup>const state = reactive({title: '标题',name: 'wff'})const name = toRef(state, 'name')console.log(state.name)console.log(name.value)
</script><template><div>name:{{name}}</div>
</template>

七、toRefs()

toRefs() 函数将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象相应属性的 ref。

<script setup>const state = reactive({title: '标题',name: 'wff'})const { title } = toRefs(state)console.log(state.title)console.log(title.value)
</script><template><div>title:{{title}}</div>
</template>

注:我们使用 reactive创建的对象,如果想在模板中使用,就必须得使用 xxx.xxx的形式;如果大量用到的话还是很麻烦的,但是使用 es6解构以后,会失去响应式。那么toRefs的作用就体现在这,利用toRefs可以将一个响应式 reactive 对象的所有原始属性转换为响应式的ref属性

八、toRaw()

toRaw() 函数可以返回由 reactive()readonly()shallowReactive() 或者 shallowReadonly() 创建的代理对应的原始对象(将响应式对象转化为普通对象)。

这是一个可以用于临时读取而不引起代理访问/跟踪开销,或是写入而不触发更改的特殊方法。不建议保存对原始对象的持久引用,请谨慎使用。

const foo = {}
const reactiveFoo = reactive(foo)console.log(toRaw(reactiveFoo) === foo) // true

九、ref、toRef、toRefs 异同点

  • ref、toRef、toRefs 函数都可以将某个对象中的属性变成响应式数据

  • ref 函数的本质是拷贝,修改响应式数据,不会影响到原始数据(引用数据类型会有影响),视图会更新

  • toRef、toRefs 函数和传入的数据形成引用关系,修改 toRef 会影响这些数据,但是不会更新视图

    作用:把一个响应式对象转换成普通对象,该普通对象的每个属性都是一个 ref

    • toRef 函数一次仅能设置一个数据,接收两个参数,第一个参数是哪个对象,第二个参数是对象的哪个属性
    • toRefs 函数接收一个对象作为参数,它会遍历对象身上的所有属性,然后挨个调用 toRef 执行。用于批量设置多个数据为响应式
  • ref 数据会引起监听行为,而 toRef 不会

相关文章:

【Vue3 知识第七讲】reactive、shallowReactive、toRef、toRefs 等系列方法应用与对比

文章目录 一、reactive()二、readonly()三、shallowReactive()四、shallowReadonly()五、isReactive() 和 isReadonly()六、toRef()七、toRefs()八、toRaw()九、ref、toRef、toRefs 异同点 一、reactive() reactive() 函数用于返回一个对象的响应式代理。与 ref() 函数定义响应…...

Docker 摸门级简易手册

Docker 摸门级简易手册 文章目录 Docker 摸门级简易手册使用 Docker 构建 Java 项目镜像Docker 安装Install on MacInstall on WindowsInstall on Linux Dockerfile 说明FROMLABELENVWORKDIRCOPYADDRUNCMDEXPOSEENTRYPOINTVOLUMEUSER 使用 Docker 构建 Java 项目镜像 假设有个…...

Java类加载机制

简介 在Java的世界里&#xff0c;每一个类或者接口&#xff0c;在经历编译器后&#xff0c;都会生成一个个.class文件。 类加载机制指的是将这些.class文件中的二进制数据读入到内存中&#xff0c;并对数据进行校验&#xff0c;解析和初始化。最终&#xff0c;每一个类都会在…...

vue 自定义指令简单记录

自定义指令例子 // src/main.js import { createApp } from vue; import App from ./App.vue;const app = createApp(App);// 全局自定义指令 app.directive(color-directive, {mounted(el, binding) {// 当指令绑定到元素上时触发// el 是绑定的元素// binding 包含了指令的信…...

算法通关村-----快速排序的原理和实现

快速排序介绍 快速排序是一种经典高效的排序方法&#xff0c;是分治策略在排序上的具体体现。将一个大的待排序列分割成若干个小的有序序列&#xff0c;最终将各个小的有序序列合并成一个大的有序序列。 快速排序的实现原理 选择一个基准值&#xff0c;将小于基准值的元素放…...

百度抓取香港服务器抓取超时是什么情况?

​ 网络延迟导致抓取超时 网络延迟是指从发送请求到接收响应之间的时间延迟。如果网络延迟过高&#xff0c;服务器可能无法及时响应请求&#xff0c;导致超时。在香港服务器上抓取数据时&#xff0c;如果网络延迟过高&#xff0c;可能会出现抓取超时的情况。 服务器负载过高可能…...

Springboot上传文件

上传文件示例代码&#xff1a; ApiOperation("上传文件") PostMapping(value "/uploadFile", consumes MediaType.MULTIPART_FORM_DATA_VALUE) public ApiResult<String> uploadFile(RequestPart("file") MultipartFile file) { //调用七…...

kafka教程

kafka教程 Kafka是一个分布式、分区的、多副本的、多订阅者&#xff0c;基于zookeeper协调的分布式日志系统&#xff0c;其主要特点为&#xff1a; 以时间复杂度为O(1)的方式提供消息持久化能力&#xff0c;即使对TB级以上数据也能保证常数时间的访问性能高吞吐率。即使在非常…...

JVM的故事—— 内存分配策略

内存分配策略 文章目录 内存分配策略一、对象优先在Eden分配二、大对象直接进入老年代三、长期存活的对象将进入老年代四、动态对象年龄判定五、空间分配担保 一、对象优先在Eden分配 堆内存有新生代和老年代&#xff0c;新生代中有一个Eden区和一个Survivor区(from space或者…...

21.CSS的动态圆形进度条

效果 源码 <!doctype html> <html><head><meta charset="utf-8"><title>Animated Circular Progress | CSS Only</title><link rel="stylesheet" href="style.css"></head><body><di…...

Linux_VMware_虚拟机磁盘扩容

来源文章 &#xff1a;VMware教学-虚拟机扩容篇_vmware虚拟机扩容_系统免驱动的博客-CSDN博客 由于项目逐步的完善&#xff0c;需要搭建的中间件&#xff0c;软件越来越多&#xff0c;导致以前虚拟机配置20G的内存不够用了&#xff0c;又不想重新创建新的虚拟机&#xff0c;退…...

中欧财富:分布式数据库的应用历程和 TiDB 7.1 新特性探索

原文来源&#xff1a; https://tidb.net/blog/ccbaeda2 作者&#xff1a;张政俊&#xff0c; 中欧财富数据库负责人 导读 中欧财富是中欧基金控股的销售子公司&#xff0c;旗下 APP 实现业内基金品种全覆盖&#xff0c;提供基金交易、大数据选基、智慧定投、理财师咨询等…...

树莓 LUMA-OLED.EXAMPLE使用

详细介绍在文件目录下的README.rst中 第一步 $ sudo usermod -a -G i2c,spi,gpio pi //好像没什么用 $ sudo apt install python3-dev python3-pip python3-numpy libfreetype6-dev libjpeg-dev build-essential //安装依赖包&#xff0c;树莓派中好像已经有了 $ sudo a…...

C#,《小白学程序》第十一课:双向链表(Linked-List)其二,链表的插入与删除的方法(函数)与代码

1 文本格式 /// <summary> /// 改进的车站信息类 class /// 增加了 链表 需要的两个属性 Last Next /// </summary> public class StationAdvanced { /// <summary> /// 编号 /// </summary> public int Id { get; set; } 0; ///…...

java IDEA文件路径分层级

如下图这样 在设置里找到Compact Middle Packages&#xff0c;去掉勾选就行了...

Spring AOP+Redis实现接口访问限制

目录 一、需求二、实现思路三、代码实现3.1 导入依赖3.2 配置redis3.3 自定义注解3.4 定义切面类3.5 自定义异常类3.6 全局异常处理器 一、需求 在我们程序中&#xff0c;有时候需要对一些接口做访问控制&#xff0c;使程序更稳定&#xff0c;最常用的一种是通过ip限制&#x…...

互联网后端技术大全!

互联网后端技术大全&#xff01; 一. 系统开发 高内聚/低耦合 高内聚 高内聚指一个软件模块是由相关性很强的代码组成&#xff0c;只负责一项任务&#xff0c;也就是常说的单一责任原则。模块的内聚反映模块内部联系的紧密程度。 低耦合 模块之间联系越紧密&#xff0c;其…...

Android SDK 上手指南||第九章 Manifest文件

第九章 Manifest文件 到目前为止&#xff0c;我们已经熟悉了Android项目中的各个组成部分&#xff0c;包括其资源。在今天的文章中&#xff0c;我们将以项目Manifest文件作为核心内容。 对于一个项目来说&#xff0c;Manifest既可以很简单、也可以很复杂&#xff0c;其具体情…...

CVE-2023-3450:锐捷 RG-BCR860 命令执行漏洞复现

锐捷 RG-BCR860 命令执行漏洞(CVE-2023-3450)复现 0x01 前言 本次测试仅供学习使用&#xff0c;如若非法他用&#xff0c;与本文作者无关&#xff0c;需自行负责&#xff01;&#xff01;&#xff01; 0x02 漏洞描述 Ruijie Networks RG-BCR860是中国锐捷网络&#xff08;R…...

【ES】elasticsearch8.3.3

这里仅实践操作并根据实际问题进行记录笔记。 运行 ES8 我们需要在自己的电脑上安装好 Docker Desktop。接着我们运行如下的命令&#xff1a;出现两个异常&#xff0c;一个是需要使用winpty因为我使用win的docker desktop&#xff0c;另外一个问题是docker启动elasticsearchE…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...

小木的算法日记-多叉树的递归/层序遍历

&#x1f332; 从二叉树到森林&#xff1a;一文彻底搞懂多叉树遍历的艺术 &#x1f680; 引言 你好&#xff0c;未来的算法大神&#xff01; 在数据结构的世界里&#xff0c;“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的&#xff0c;它…...

STM32标准库-ADC数模转换器

文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”&#xff1a;输入模块&#xff08;GPIO、温度、V_REFINT&#xff09;1.4.2 信号 “调度站”&#xff1a;多路开关1.4.3 信号 “加工厂”&#xff1a;ADC 转换器&#xff08;规则组 注入…...

webpack面试题

面试题&#xff1a;webpack介绍和简单使用 一、webpack&#xff08;模块化打包工具&#xff09;1. webpack是把项目当作一个整体&#xff0c;通过给定的一个主文件&#xff0c;webpack将从这个主文件开始找到你项目当中的所有依赖文件&#xff0c;使用loaders来处理它们&#x…...

Xcode 16 集成 cocoapods 报错

基于 Xcode 16 新建工程项目&#xff0c;集成 cocoapods 执行 pod init 报错 ### Error RuntimeError - PBXGroup attempted to initialize an object with unknown ISA PBXFileSystemSynchronizedRootGroup from attributes: {"isa">"PBXFileSystemSynchro…...

门静脉高压——表现

一、门静脉高压表现 00:01 1. 门静脉构成 00:13 组成结构&#xff1a;由肠系膜上静脉和脾静脉汇合构成&#xff0c;是肝脏血液供应的主要来源。淤血后果&#xff1a;门静脉淤血会同时导致脾静脉和肠系膜上静脉淤血&#xff0c;引发后续系列症状。 2. 脾大和脾功能亢进 00:46 …...