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

vue3.0(五) reactive全家桶

文章目录

  • 1 reactive
    • 1.1 reactive的应用
    • 1.2 reactive的特点
    • 1.3 reactive的注意
    • 1.4 reactive的局限性
  • 2 toRefs
  • 3 isReactive
  • 4 shallowReactive
  • 5 readonly
    • 5.1 readonly 详细信息
    • 5.2 readonly函数创建一个只读的响应式对象
    • 5.3 如何修改嵌套在只读响应式对象中的对象?
  • 6 isReadonly
  • 7 shallowReadonly
  • 8 isProxy
  • 总结


1 reactive

1.1 reactive的应用

reactive是另一种声明响应式状态的方式,与将内部值包装在特殊对象中的 ref 不同,reactive() 将使对象本身具有响应性:

import { reactive } from 'vue'
// 声明state
const state = reactive({ count: 0 })
// js中的应用和ref不同不需要valueconsole.log(state)
// html模版中应用<div>{{ state.count }}</div>

响应式对象是 JavaScript 代理,其行为就和普通对象一样。不同的是,Vue 能够拦截对响应式对象所有属性的访问和修改,以便进行依赖追踪和触发更新。
reactive() 将深层地转换对象:当访问嵌套对象时,它们也会被 reactive() 包装。当 ref 的值是一个对象时,ref() 也会在内部调用它。与浅层 ref 类似,这里也有一个 shallowReactive() API 可以选择退出深层响应性。

1.2 reactive的特点

  • 实现引用类型数据的响应式,如数组、对象等
  • ref去创建引用类型的响应式,其实内部也是调用了reactive
  • reactive创建的响应式对象,调用时不用.value

在Vue3中,reactive函数是用于创建响应式对象的函数。它接收一个普通对象作为参数,返回一个代理对象。这个代理对象可以拦截对象的get和set操作,并在其中实现响应式的逻辑。当我们读取代理对象的属性时,会触发依赖收集;当我们修改代理对象的属性时,会触发相应的依赖更新。在调用reactive函数时,Vue3会使用Proxy对象对传入的对象进行代理,从而实现响应式的特性。

1.3 reactive的注意

  • reactive() 返回的是一个原始对象的 Proxy,它和原始对象是不相等的:
    const obj = {}
    const proxy = reactive(obj)
    // 代理对象和原始对象不是全等的
    console.log(proxy === obj) // false
    
  • 为保证访问代理的一致性,对同一个原始对象调用 reactive() 会总是返回同样的代理对象,而对一个已存在的代理对象调用 reactive() 会返回其本身:
    const obj = {}
    const proxy = reactive(obj)
    // 在同一个对象上调用 reactive() 会返回相同的代理
    console.log(proxy === reactive(obj)) // true
    // 在一个代理上调用 reactive() 会返回它自己
    console.log(reactive(proxy) === proxy) // true
    

1.4 reactive的局限性

  1. 有限的值类型:它只能用于对象类型 (对象、数组和如 Map、Set 这样的集合类型)。它不能持有如 string、number 或 boolean 这样的原始类型。
  2. 不能替换整个对象:由于 Vue 的响应式跟踪是通过属性访问实现的,因此我们必须始终保持对响应式对象的相同引用。这意味着我们不能轻易地“替换”响应式对象,因为这样的话与第一个引用的响应性连接将丢失:
<template><div>{{ state.count }}</div><button @click="mutateDeeply">修改数据</button>
</template>
<script lang="ts">
import { defineComponent, reactive } from 'vue'
export default defineComponent({setup () {let state = reactive({ count: 1 })console.log(state)function mutateDeeply () {// 对state进行替换响应式对象// 上面的 ({ count: 0 }) 引用将不再被追踪// (响应性连接已丢失!)state = reactive({ count: 2 })console.log(state, state.count)}return {mutateDeeply,state}}
})
</script>

当点击修改数据按钮时,打印的是赋值的数据,但是页面并未更新,(响应性连接已丢失!)

  1. 对解构操作不友好:当我们将响应式对象的原始类型属性解构为本地变量时,或者将该属性传递给函数时,我们将丢失响应性连接:
    <template><div>{{ state.count }}</div><button @click="mutateDeeply">修改数据</button>
    </template>
    <script lang="ts">
    import { defineComponent, ref, reactive } from 'vue'
    export default defineComponent({setup () {const state = reactive({ count: 1 })console.log(state)function mutateDeeply () {// 当解构时,count 已经与 state.count 断开连接let { count } = state// 不会影响原始的 statecount++console.log(state, state.count, count)}return {container,mutateDeeply,state}}
    })
    </script>
    <style scoped>
    </style>
    

上述代码执行结果

2 toRefs

  1. 将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象相应属性的 ref。每个单独的 ref 都是使用 toRef() 创建的。
     const state = reactive({foo: 1,bar: 2})const stateAsRefs = toRefs(state)/*stateAsRefs 的类型:{foo: Ref<number>,bar: Ref<number>}*/// 这个 ref 和源属性已经“链接上了”console.log(stateAsRefs) // {foo: ObjectRefImpl, bar: ObjectRefImpl}state.foo++console.log(stateAsRefs.foo.value)// 2stateAsRefs.foo.value++console.log(state.foo)// 3
    
    1. 组件可以解构/展开返回的对象而不会失去响应性:
    <template><div>{{ state.foo }}</div><div>{{ state.bar }}</div><button @click="mutateDeeply">修改数据</button>
    </template>
    <script lang="ts">
    import { defineComponent, reactive, toRefs } from 'vue'
    export default defineComponent({setup () {const state = reactive({foo: 1,bar: 2})function useFeatureX () {return toRefs(state)}function mutateDeeply () {const { foo, bar } = useFeatureX()foo.value++bar.value++console.log(foo.value, bar.value)}return {mutateDeeply,state}}
    })
    </script>
    <style scoped>
    </style>
    

上述代码执行效果
toRefs 在调用时只会为源对象上可以枚举的属性创建 ref。如果要为可能还不存在的属性创建 ref,请改用 toRef。

3 isReactive

检查一个对象是否是由 reactive() 或 shallowReactive() 创建的代理。

const state = readonly(reactive({count: 1,name: 'Tom'
}))console.log(state.count)// 1
console.log(state.name)// Tom
console.log(isReactive(state)) // true

4 shallowReactive

  1. reactive() 的浅层作用形式。
  2. 和 reactive() 不同,这里没有深层级的转换:一个浅层响应式对象里只有根级别的属性是响应式的。属性的值会被原样存储和暴露,这也意味着值为 ref 的属性不会被自动解包了
<template><div>{{ state.foo }}</div><div>{{ state.nested.bar }}</div><button @click="mutateDeeply">修改数据</button>
</template>
<script lang="ts">
import { defineComponent, shallowReactive, isReactive } from 'vue'
export default defineComponent({setup () {const state = shallowReactive({foo: 1,nested: {bar: 2}})// ...但下层嵌套对象不会被转为响应式console.log(isReactive(state.nested)) // falsefunction mutateDeeply () {state.foo++// 不是响应式的 数据state.nested.bar++console.log(state.foo, state.nested, state.nested.bar)}return {mutateDeeply,state}}
})
</script>

5 readonly

接受一个对象 (不论是响应式还是普通的) 或是一个 ref,返回一个原值的只读代理。

5.1 readonly 详细信息

  • 只读代理是深层的:对任何嵌套属性的访问都将是只读的。它的 ref 解包行为与 reactive() 相同,但解包得到的值是只读的。
  • 要避免深层级的转换行为,请使用 shallowReadonly() 作替代。

5.2 readonly函数创建一个只读的响应式对象

  const state = readonly(reactive({count: 1,name: 'Tom'}))console.log(state.count)// 1console.log(state.name)// Tom

5.3 如何修改嵌套在只读响应式对象中的对象?

使用readOnly函数创建的只读对象,内部的属性无法修改

   const state = readonly(reactive({count: 1,name: 'Tom'}))console.log(state.count)// 1state.name = 'diXi' // 输出警告信息,不会触发依赖更新console.log(state.name)// Tom

在这里插入图片描述
注意:使用 readonly 函数创建的只读响应式对象是深层只读的。也就是说,当我们尝试修改嵌套在只读响应式对象中的对象时,会输出警告信息,不会触发相应的依赖更新。

6 isReadonly

  • 检查传入的值是否为只读对象。只读对象的属性可以更改,但他们不能通过传入的对象直接赋值。
  • 通过 readonly() 和 shallowReadonly() 创建的代理都是只读的,因为他们是没有 set 函数的 computed() ref。
const state = readonly(reactive({count: 1,name: 'Tom'}))console.log(state.count)// 1console.log(state.name)// Tomconsole.log(isReadonly(state)) // true

7 shallowReadonly

  • readonly() 的浅层作用形式
  • 和 readonly() 不同,这里没有深层级的转换:只有根层级的属性变为了只读。属性的值都会被原样存储和暴露,这也意味着值为 ref 的属性不会被自动解包了。
    const state1 = readonly(reactive({foo: 1,nested: {bar: 2}}))const state = shallowReadonly(reactive({foo: 1,nested: {bar: 2}}))console.log(state.nested.bar++)// console.log(state1.nested.bar++) // 报错 Cannot assign to 'bar' because it is a read-only property// console.log(state.foo++) // 报错 Cannot assign to 'bar' because it is a read-only property// console.log(state1.foo++) // 报错 Cannot assign to 'bar' because it is a read-only property// ...但可以更改下层嵌套对象isReadonly(state.nested) // false

8 isProxy

检查一个对象是否是由 reactive()、readonly()、shallowReactive() 或 shallowReadonly() 创建的代理。

   const state = readonly(reactive({count: 1,name: 'Tom'}))console.log(state.count)// 1console.log(state.name)// Tomconsole.log(isProxy(state)) // true

总结

Vue3中用于创建响应式对象的三个函数:
reactive、readonly和shallowReactive。
reactive函数用于创建深层响应式对象,
shallowReactive函数用于创建浅层响应式对象,
readonly函数用于创建深层只读响应式对象,
shallowReadonly函数用于创建浅层只读响应式对象。
这些函数可以帮助我们快速创建响应式数据,实现数据的自动更新。
isProxy,isReadonly,isReactive判断是否是相应是对象
isProxy 检查一个对象是否是由 reactive()、readonly()、shallowReactive() 或 shallowReadonly() 创建的代理。
isReadonly 检查传入的值是否为 readonly() 和 shallowReadonly() 创建的只读对象。
isReactive 检查一个对象是否是由 reactive() 或 shallowReactive() 创建的代理。

相关文章:

vue3.0(五) reactive全家桶

文章目录 1 reactive1.1 reactive的应用1.2 reactive的特点1.3 reactive的注意1.4 reactive的局限性 2 toRefs3 isReactive4 shallowReactive5 readonly5.1 readonly 详细信息5.2 readonly函数创建一个只读的响应式对象5.3 如何修改嵌套在只读响应式对象中的对象? 6 isReadonl…...

Selenium 自动化 —— 四种等待(wait)机制

更多关于Selenium的知识请访问CSND论坛“兰亭序咖啡”的专栏&#xff1a;专栏《Selenium 从入门到精通》 ​ 目录 目录 需要等待的场景 自己实现等待逻辑 Selenium 提供的三种等待机制 隐式等待&#xff08;Implicit Waits&#xff09; 隐式等待的优点 隐式等待的缺点 …...

每日两题 / 437. 路径总和 III 105. 从前序与中序遍历序列构造二叉树(LeetCode热题100)

437. 路径总和 III - 力扣&#xff08;LeetCode&#xff09; 前序遍历时&#xff0c;维护当前路径&#xff08;根节点开始&#xff09;的路径和&#xff0c;同时记录路径上每个节点的路径和 假设当前路径和为cur&#xff0c;那么ans 路径和(cur - target)的出现次数 /*** D…...

matlab使用2-基础绘图

matlab使用2-基础绘图 文章目录 matlab使用2-基础绘图1. 二维平面绘图2. 三维立体绘图3. 图形窗口的分割 1. 二维平面绘图 % 创建一些二维数据 x 0:0.01:10; % x轴的数据点&#xff0c;从0到10&#xff0c;间隔为0.01 y sin(x); % y轴的数据点&#xff0c;是x的正弦…...

嵌入式开发四大平台介绍

MCU&#xff08;Micro Control Unit&#xff09;四大平台介绍&#xff09; 单片机优点&#xff1a;缺点&#xff1a;总结&#xff1a; DSP digital signal processingARM优点&#xff1a;缺点&#xff1a;总结 FPGA什么事FPGA&#xff08;集成元件库&#xff09;FPGA开发方法—…...

《Python编程从入门到实践》day28

# 昨日知识点回顾 安装Matplotlib 绘制简单的折线图 # 今日知识点学习 15.2.1 修改标签文字和线条粗细 # module backend_interagg has no attribute FigureCanvas. Did you mean: FigureCanvasAgg? # 解决办法&#xff1a;matplotlib切换图形界面显示终端TkAgg。 #…...

STC8增强型单片机开发【定时器Timer⭐】

目录 一、引言 二、定时器基础知识 三、STC8定时器配置 四、代码示例 五、总结 一、引言 在单片机开发中&#xff0c;定时器&#xff08;Timer&#xff09;是一个极其重要的组件&#xff0c;它允许开发者基于时间触发各种事件或任务。STC8增强型单片机作为一款功能丰富的…...

C语言实训项目源码-02餐厅饭卡管理系统-C语言实训C语言大作业小项目

C语言餐厅饭卡管理系统 一、主要功能 主要功能模块 页面名称 实现功能 负责人 进入页面 进入程序 主函数 系统主要功能 修改密码函数 修改密码 充值&#xff0c;显示函数 饭卡充值与信息显示 购买饭菜…...

Linux第四节--常见的指令介绍集合(持续更新中)

点赞关注不迷路&#xff01;本节涉及初识Linux第四节&#xff0c;主要为常见的几条指令介绍。 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x1f44d;&#x1f3fb; 收藏 ✨ 加关注&#x1f440; 期待与你共同进步! 1. more指令 语法&#xff1a;more [选项][文件]…...

Apache Sqoop:高效数据传输工具搭建与使用教程

目录 引言一、环境准备二、安装sqoop下载sqoop包解压文件 三、配置Sqoop下载mysql驱动拷贝hive的归档文件配置环境变量修改sqoop-env.sh配置文件替换版本的commons-lang的jar包 验证Sqoop安装查看Sqoop版本测试Sqoop连接MySQL数据库是否成功查看数据库查看数据表去除警告信息 四…...

【C++初阶】第十一站:list的介绍及使用

目录 list的介绍及使用 1.list的含义 2.list的介绍 3.list的使用 1.list的构造 2.list iterator的使用 3.list capacity 4.list element access 5 list modifiers 尾插尾删 和 头插头删 insert 和 erase resize swap clear 6.list sort and reverse 7.list copy vector copy li…...

【devops】Linux 日常磁盘清理 ubuntu 清理大文件 docker 镜像清理

日常磁盘清理 1、查找大文件 find / -type f -size 1G2、清理docker无用镜像&#xff08;drone产生的残余镜像文件&#xff09; docker system prune -a一、清理服务器磁盘 1、查找大文件 在Ubuntu系统中&#xff0c;你可以使用find命令来查找大文件。find命令是一个强大的…...

2024年资阳市企业技术中心申报条件、流程要求及支持政策须知

第一章 总则 第一条 为深入贯彻中央、省、市大力实施创新驱动发展战略的部署要求&#xff0c;进一步强化企业技术创新主体地位&#xff0c;引导和支持企业增强技术创新能力&#xff0c;健全技术创新市场导向机制&#xff0c;规范我市企业技术中心&#xff08;下称“市企业技术…...

社交媒体数据恢复:如流

如流&#xff0c;原名百度Hi&#xff0c;是百度公司开发的一款即时通讯软体。百度Hi具备文字消息、视讯、通话、文件传输等功能。 查找备份&#xff1a;如果您之前有备份如流中的数据&#xff0c;您可以尝试从备份中恢复。如流支持备份至云端&#xff0c;如百度网盘等。 联系客…...

【微信小程序开发(从零到一)【婚礼邀请函】制作】——任务分析和效果实现的前期准备(1)

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…...

独孤思维:模仿别人赚钱太难,很痛苦

01 独孤早年混群的时候&#xff0c;想着成为群红&#xff0c;引流。 结果不得其法&#xff0c;别人要什么项目&#xff0c;我就把满是钩子的副业资料发群里。 被群主踢了出去。 我当时还不理解。 后来自己做了社群以后&#xff0c;才明白&#xff0c;这种行为&#xff0c;…...

图片转base64【Vue + 纯Html】

1.template <el-form-item label"图片"><div class"image-upload-container"><input type"file" id"imageUpload" class"image-upload" change"convertToBase64" /><label for"imageU…...

【从零开始学习Redis | 第十一篇】快速介绍Redis持久化策略

前言&#xff1a; Redis 作为一种快速、高效的内存数据库&#xff0c;被广泛应用于缓存、消息队列、会话存储等场景。然而&#xff0c;由于其特性是基于内存的&#xff0c;一旦服务器进程退出&#xff0c;内存中的数据就会丢失。为了解决这一问题&#xff0c;Redis 提供了持久…...

在Ubuntu中如何解压zip压缩包??

2024年5月15日&#xff0c;周三上午 使用 unzip 命令 unzip 文件名.zip这会将压缩包中的内容解压到当前目录。如果想解压到特定目录&#xff0c;可以使用 -d 选项&#xff0c;例如&#xff1a; unzip 文件名.zip -d 目标目录使用 7-zip 还可以安装 7-zip 工具来解压 ZIP 文件。…...

LeetCode 126题:单词接龙 II

❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容&#xff0c;和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣&#xff01; 推荐&#xff1a;数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注 导航&#xff1a; LeetCode解锁100…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像&#xff08;比如分辨率3000*3000的图像&#xff09;的办法&#xff0c;尤其是想把内存中的裸数据&#xff08;只有图像的数据&#xff0c;不包…...

【C++】纯虚函数类外可以写实现吗?

1. 答案 先说答案&#xff0c;可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...