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

vue3中的reactive、ref、toRef和toRefs

目录

  • reactive
    • reactive的实现原理
    • 使用reactive的注意事项
  • ref
    • ref的实现原理
    • 使用ref的注意事项
  • toRef和toRefs
  • ref和reactive的使用比较

reactive

reactive用于创建响应式对象,它返回一个对象的响应式代理。即:它返回的对象以及其中嵌套的对象都会通过 Proxy 包裹;当响应式对象被访问时,触发getter方法;当响应式对象被修改时,触发setter方法。在使用响应式对象时,我们可以像普通对象一样访问和修改数据。

使用reactive的示例代码

<template><div> {{ state.name }} --- {{ state.age }}</div>
</template>
<script setup> 
import { reactive } from 'vue';
const state = reactive({name: 'jack',age: 22
})
</script>
<style scoped>
</style>

reactive的实现原理

reactive是利用ES6的Proxy对象来实现的。当我们使用reactive函数对一个对象进行响应式处理时,Vue3会创建一个Proxy,拦截该对象的所有属性的读取和修改操作,从而实现监听属性的变化,并在变化时触发相关的响应式更新。

reactive实现原理的简单示意代码如下:

function reactive(obj) {if(typeof obj !== 'object' || obj === null) {return obj;}// 防止响应式重复包裹if(obj.__v_reactive) {return obj;}const observed = new Proxy(obj, {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 = Reflect.get(target, key, receiver);let result = true;if(oldValue !== value) {result = Reflect.set(target, key, value, receiver);// 触发更新trigger(target, TriggerOpTypes.SET, key, value, oldValue);}return result;},deleteProperty(target, key) {const hasKey = hasOwn(target, key);const oldValue = target[key];const result = Reflect.deleteProperty(target, key);if(hasKey && result) {// 触发更新trigger(target, TriggerOpTypes.DELETE, key, undefined, oldValue);}return result;}});// 标记为响应式对象observed.__v_reactive = true; return observed;
}

上述代码中,reactive函数接收一个对象 obj,如果 obj 不是对象或为 null,返回原值。如果 obj 已经被处理为响应式,则直接返回该响应式对象。

使用reactive的注意事项

  1. reactive只能处理对象和数组,如果传入非对象或数组的参数将会直接返回,不会进行响应式处理。

  2. 对于给定的对象,reactive将会递归收集其中所有子属性的依赖关系,因此在实际开发中,尽量不要嵌套过深,否则可能会影响性能。

  3. reactive处理后的对象,不能直接用于解构赋值操作,建议采用Vue3提供的toRefs函数将响应式对象转换成普通对象后再进行操作。

  4. 在组件的setup函数中,需要使用ref或reactive对数据进行响应式处理后才能使用,在函数外部创建的响应式对象也必须在组件的setup函数中使用才能确保响应式生效。

ref

关于ref的相关特性,我在前面的博客中有讲过其用于注册元素或子组件的引用时的用法,这里就不在充分讲了,只对前面博客没有提到的响应式进行探讨。

ref 接受一个内部值,返回一个响应式的、可更改的 ref 对象,此对象只有一个指向其内部值的属性 .value。它将一个基本类型数据包装为响应式对象。

ref 对象是可更改的,我们可以通过 .value 属性来修改它的值。它也是响应式的,即所有对 .value 的操作都将被追踪,并且写操作会触发与之相关的副作用。

如果将一个对象赋值给 ref,那么这个对象将通过 reactive() 转为具有深层次响应式的对象。这也意味着如果对象中包含了嵌套的 ref,它们将被深层地解包。

ref的实现原理

ref是基于基于Vue 3中的reactive和proxy两个API来实现的,proxy通过创建拦截器对象来在对象上设置自定义行为。它用于拦截对ref对象的读取和写入操作,以便在改变ref值时通知Vue响应式系统来更新视图。

ref实现原理的简单示意代码如下:

function ref(value) {return reactive({value,get unbox() {return this.value}})
}

在这里,我们通过将value作为响应式对象的一个属性,从而使得value变为响应式。同时,我们通过unbox属性提供了一个获取value的值的便捷方法。

使用ref的注意事项

  1. ref只能用于包装简单类型的数据,如字符串、数字、布尔值等独立的基本数据类型,或者对象、数组、函数等引用类型的数据。不建议将ref用于包装复杂的嵌套数据结构,因为这会增加处理和维护的复杂性。

  2. 在组件内使用ref时,建议在setup()函数内创建ref成员变量,并在组件模板中使用模板引用(template refs)来引用它。

  3. ref只能用于包装可变变量,不应用于包装不可变变量或常量,因为这样会导致无法更新变量的值。

  4. 在对ref对象进行操作时,应该使用.value属性来访问其内部的响应式值,而不是直接操作ref对象本身。

  5. 不要在ref对象上定义额外的属性或方法,因为这些属性和方法不会被响应式系统跟踪,也不会触发视图更新。如果需要在ref对象上定义属性或方法,应该使用reactive对象来包装它们。

toRef和toRefs

toRef和toRefs是vue中两个非常重要的工具函数。它们可以将一个响应式对象的属性,转换成一个Ref对象或者Ref对象集合,使得这些属性可以在组件中被使用。

  1. toRef:toRef函数将响应式对象的其中一个属性转换成一个Ref对象。

    toRef的一个简单示例

    <template><div> {{ nameRef}} </div>
    </template>
    <script setup>  
    import { reactive, toRef } from 'vue'	
    const state = reactive({name: 'Vue 3',version: '3.0.0'
    })	
    const nameRef = toRef(state, 'name')
    </script>	
    <style scoped>	
    </style>	
    
  2. toRefs:toRefs函数将一个响应式对象的全部属性转换成Ref对象集合。

    toRefs的一个简单示例

    <template><div> {{ refs.name }} ---{{ refs.version }}</div>
    </template>
    <script setup>  
    import { reactive, toRefs } from 'vue'const state = reactive({name: 'Vue 3',version: '3.0.0'
    })const refs = toRefs(state)
    </script>
    <style scoped>
    </style>
    

ref和reactive的使用比较

Ref和Reactive都是响应式对象。它们的区别在于:

Ref是一个基本类型的响应式容器,通过.value访问,适用于基本类型或者简单对象的响应式数据。

Reactive是一个对象级别的响应式容器,适用于复杂的对象或者数组的响应式数据。

下面是一个示例代码,展示了Ref和Reactive的区别和使用场景:

<template><div> {{ count }} ---{{ doubleCount }} <br>{{ state.count }} ---{{ state.doubleCount }}</div>
</template>
<script setup>  
import { ref, reactive,watch } from 'vue'
// 1. Ref示例代码
const count = ref(0)
const doubleCount = ref(0)
watch(count, () => {doubleCount.value = count.value * 2
})
// 2. Reactive示例代码
const state = reactive({count: 0,doubleCount: 0
})
watch(() => state.count, () => {state.doubleCount = state.count * 2
})
</script>
<style scoped>
</style>

上述代码中,我们通过Ref对象和Reactive对象来实现同一个数据的响应式处理。可以看出,Ref对象使用简单,适用于单一的基本类型数据,而Reactve对象则复杂些,适用于复杂的对象和数组数据。

OK,关于vue3中的reactive、ref、toRef和toRefs相关的使用方法就介绍到这里,喜欢的小伙伴点赞关注加收藏哦!

相关文章:

vue3中的reactive、ref、toRef和toRefs

目录 reactivereactive的实现原理使用reactive的注意事项 refref的实现原理使用ref的注意事项 toRef和toRefsref和reactive的使用比较 reactive reactive用于创建响应式对象&#xff0c;它返回一个对象的响应式代理。即&#xff1a;它返回的对象以及其中嵌套的对象都会通过 Pr…...

数字图像处理与Python实现-图像增强经典算法汇总

图像增强经典算法汇总 文章目录 图像增强经典算法汇总1、像素变换2、图像逆变换3、幂律变换4、对数变换5、图像均衡化6、对比度受限自适应直方图均衡(CLAHE)7、对比度拉伸8、Sigmoid校正9、局部对比度归一化10、总结本文将对图像增强经典算法做一个简单的汇总。图像增强的经典…...

tag提示词总结

顺序的权重 越靠前的tag权重越大&#xff0c;越靠后的tag权重越小经验来讲&#xff0c;将图像质量相关的tag放在前面&#xff0c;例如masterpiece&#xff0c;best quality等&#xff1b;接着添加主体画风等&#xff1b;最后添加一些不太重要的细节 权重增减 (tag)&#xff1a…...

微信小程序原生开发功能合集二十:导航栏、tabbar自定义及分包功能介绍

本章实现导航栏及tabbar的自定义处理的相关方法介绍及效果展示。   另外还提供小程序开发基础知识讲解课程,包括小程序开发基础知识、组件封装、常用接口组件使用及常用功能实现等内容,具体如下:    1. CSDN课程: https://edu.csdn.net/course/detail/37977    2. 5…...

高通 Camera HAL3:项目开发技术点总结

做高通 Camera HAL3开发的一些技术点的总结、整理。 做个记录&#xff0c;方便后续查阅。 1.目录、so、配置文件 productName是项目名 out Target路径&#xff1a;\out\target\product\productName\chi-cdk&#xff1a;\vendor\qcom\proprietary\chi-cdk\ldc node&#xff1…...

chatgpt赋能python:Python怎么删除列表中的最大值和最小值

Python怎么删除列表中的最大值和最小值 在Python中&#xff0c;一个列表&#xff08;List&#xff09;是一种非常常见的数据结构&#xff0c;它允许我们以有序的方式存储和访问数据。但是&#xff0c;有时候我们需要从列表中删除最大或最小的值&#xff0c;以满足我们的特定需…...

简述Vue的生命周期以及每个阶段做的事情

03_简述Vue的生命周期以及每个阶段做的事情 思路 给出概念 列举出生命周期各个阶段 阐述整体流程 结合实际 扩展&#xff1a;vue3变化 回答范例 每个vue组件实例被创建后都会经过一系列步骤。比如它需要数据观测、模板编译、挂载实例到dom、以及数据变化的时候更新dom、…...

LeetCode-C#-0004.寻找两个正序数组的中位数

0.声明 该题目来源于LeetCode 如有侵权&#xff0c;立马删除。 解法不唯一&#xff0c;如有新解法可一同讨论。 1.题目 0004寻找两个正序数组的中位数 给定两个大小分别为m和n的正序&#xff08;从小到大&#xff09;数组nums1和nums2。 请你找出并返回着两个正序数组的中位…...

Vue.js 中的 $emit 和 $on 方法有什么区别?

Vue.js 中的 $emit 和 $on 方法有什么区别&#xff1f; 在 Vue.js 中&#xff0c;$emit 和 $on 方法是两个常用的方法&#xff0c;用于实现组件间的通信。它们可以让我们在一个组件中触发一个自定义事件&#xff0c;并在另一个组件中监听这个事件&#xff0c;从而实现组件间的…...

LAZADA平台的商品评论Python封装API接口接入文档和参数说明

LAZADA是一个位于东南亚的电商平台&#xff0c;成立于2012年。该平台覆盖的国家包括新加坡、马来西亚、印尼、菲律宾、泰国和越南等地。它提供了一个多样化的产品选择&#xff0c;包括时尚、美容、数码、母婴等商品&#xff0c;并且拥有许多知名品牌的官方旗舰店。同时&#xf…...

云原生Docker镜像管理

docker是什么&#xff1f; docker是一个go语言开发的应用容器引擎。 docker的作用&#xff1f; ①运行容器里的应用&#xff1b; ②docker是用来管理容器和镜像的一种工具。 #容器 与 虚拟机 的区别&#xff1f; 容器虚拟机所有容器共享宿主机内核每个虚拟机都有独立的操…...

ChatGPT+小红书的8种高级玩法

掌握了这套万能命令&#xff0c;让你快速做出小红书爆款文案! 一、用ChatGPT做定位 我是一个大龄的普通人&#xff0c;没有什么特殊的技能&#xff0c;接下来&#xff0c;请你作为一位小红书的账号定位专家&#xff0c;通过与我对话的方式&#xff0c;为我找到我的小红书账号定…...

shell脚本学习记录1(运算符)

Shell 传递参数 我们可以在执行 Shell 脚本时&#xff0c;向脚本传递参数&#xff0c;脚本内获取参数的格式为&#xff1a;$n。n 代表一个数字&#xff0c;1 为执行脚本的第一个参数&#xff0c;2 为执行脚本的第二个参数&#xff0c;以此类推…… 以下实例我们向脚本传递三个…...

vector 迭代器失效问题

vector 迭代器失效 迭代器的主要作用就是让算法能够不用关心底层数据结构&#xff0c;其底层实际就是一个指针&#xff0c;或者是对指针进行了封装&#xff0c;比如&#xff1a;vector的迭代器就是原生态指针T* 。因此迭代器失效&#xff0c;实际就是迭代器底层对应指针所指向…...

docker使用与服务器上的可视化(ROS rviz等)

1.安装docker 安装docker&#xff1a;官网教程&#xff0c;按照官网命令一步步来即可。 添加当前用户到docker用户组&#xff1a; 【docker】添加用户到docker组&#xff0c;这样后面运行docker的时候前面不需要加sudo命令&#xff0c;否则运行docker的时候一直需要在前面加su…...

最新版本Portraiture4.1中文版ps磨皮滤镜插件安装包

在Portraiture有非常强大的手动功能&#xff0c;可以为用户进行手动调整照片中的皮肤区域以达到更加完美的效果&#xff0c;软件还支持同时导入上千张照片&#xff0c;用户可以通过自动识别照片中的人脸从而依照自己的风格进行批量处理十分的方便快捷。 最新版本Portraiture 4…...

仓储WMS对接淘宝奇门详细说明【亲测可用】

文章目录 简介名词解释奇门对接方案前期准备系统调用流程代码实现思路关键点(个人观点)奇门对接关键代码可能遇到的问题 简介 淘宝奇门项目支持 ERP、WMS 之间的系统标准化对接&#xff0c;通过构建 ERP、WMS 系统之间标准通信协议来实现不同系统之间的打通&#xff1b;对商家…...

RFID软件:简介、功能和应用范围

在当今快节奏的商业环境中&#xff0c;RFID&#xff08;射频识别&#xff09;技术已经成为物流、供应链和库存管理等领域中不可或缺的工具。本文将向您介绍RFID软件的基本知识&#xff0c;探讨其功能和广泛应用的范围。 第一部分&#xff1a;RFID软件简介 RFID软件是一种应用…...

Android 逆向之安全防护基本策略

对抗反编译 混淆 使用混淆主要可以减小包的大小。混淆对于安全保护来说&#xff0c;只是增加了阅读难度而已。混淆不会把关键代码混淆掉&#xff0c;比如MainActivity&#xff0c;Application等&#xff0c;可以通过分析smali和阅读jar包定位代码。 资源混淆也是换汤不换药&…...

基站机房:保障通信网络稳定,如何解决安全隐患?

基站机房作为无线通信网络的关键组成部分&#xff0c;承载着大量的网络设备和通信设施&#xff0c;对于运营商和通信服务提供商来说具有重要意义。 无论是大型运营商还是通信服务提供商&#xff0c;动环监控系统都将成为他们成功运营和管理通信网络的关键工具。 客户案例 案例…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文通过代码驱动的方式&#xff0c;系统讲解PyTorch核心概念和实战技巧&#xff0c;涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...

Sklearn 机器学习 缺失值处理 获取填充失值的统计值

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...

2025.6.9总结(利与弊)

凡事都有两面性。在大厂上班也不例外。今天找开发定位问题&#xff0c;从一个接口人不断溯源到另一个 接口人。有时候&#xff0c;不知道是谁的责任填。将工作内容分的很细&#xff0c;每个人负责其中的一小块。我清楚的意识到&#xff0c;自己就是个可以随时替换的螺丝钉&…...

P10909 [蓝桥杯 2024 国 B] 立定跳远

# P10909 [蓝桥杯 2024 国 B] 立定跳远 ## 题目描述 在运动会上&#xff0c;小明从数轴的原点开始向正方向立定跳远。项目设置了 $n$ 个检查点 $a_1, a_2, \cdots , a_n$ 且 $a_i \ge a_{i−1} > 0$。小明必须先后跳跃到每个检查点上且只能跳跃到检查点上。同时&#xff0…...