vue3-响应式基础之reactive

reactive()

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

  • 「点击按钮+1」

<script lang="ts" setup>
import { reactive } from 'vue'const state = reactive({ count: 0 })</script><template><div class="container"><button @click="state.count++">点击次数加+1 : {{ state.count }}</button></div>
</template><style lang="scss" scoped>
.container {}
</style>
  • 「示例效果」

响应式对象是 JavaScript 代理,其行为就和普通对象一样。不同的是,Vue 能够拦截对响应式对象所有属性的访问和修改,以便进行依赖追踪和触发更新。

reactive() 将深层地转换对象:当访问嵌套对象时,它们也会被 reactive() 包装。当 ref 的值是一个对象时,ref() 也会在内部调用它。与浅层 ref 类似,这里也有一个 shallowReactive() API 可以选择退出深层响应性。

  • reactive() 返回的是一个原始对象的 Proxy,它和原始对象是不相等的

const raw = {}
const proxy = reactive(raw)// 代理对象和原始对象不是全等的
console.log(proxy === raw) // false

只有代理对象是响应式的,更改原始对象不会触发更新。

因此,使用 Vue 的响应式系统的最佳实践是 「仅使用你声明对象的代理版本」

  • 为保证访问代理的一致性,对同一个原始对象调用 reactive() 会总是返回同样的代理对象,而对一个已存在的代理对象调用 reactive() 会返回其本身:

// 在同一个对象上调用 reactive() 会返回相同的代理
console.log(reactive(raw) === proxy) // true// 在一个代理上调用 reactive() 会返回它自己
console.log(reactive(proxy) === proxy) // true

这个规则对嵌套对象也适用。依靠深层响应性,响应式对象内的嵌套对象依然是代理:

const proxy = reactive({})const raw = {}
proxy.nested = rawconsole.log(proxy.nested === raw) // false

reactive() 的局限性

  1. 有限的值类型:它只能用于对象类型 (对象、数组和如 Map、Set 这样的集合类型)。它不能持有如 string、number 或 boolean 这样的原始类型。

  2. 不能替换整个对象:由于 Vue 的响应式跟踪是通过属性访问实现的,因此我们必须始终保持对响应式对象的相同引用。这意味着我们不能轻易地“替换”响应式对象,因为这样的话与第一个引用的响应性连接将丢失:

let state = reactive({ count: 0 })// 上面的 ({ count: 0 }) 引用将不再被追踪
// (响应性连接已丢失!)
state = reactive({ count: 1 })
  1. 对解构操作不友好:当我们将响应式对象的原始类型属性解构为本地变量时,或者将该属性传递给函数时,我们将丢失响应性连接:

const state = reactive({ count: 0 })// 当解构时,count 已经与 state.count 断开连接
let { count } = state
// 不会影响原始的 state
count++// 该函数接收到的是一个普通的数字
// 并且无法追踪 state.count 的变化
// 我们必须传入整个对象以保持响应性
callSomeFunction(state.count)

由于这些限制,我们建议使用 ref() 作为声明响应式状态的主要 API。

额外的 ref 解包细节

  1. 作为 reactive 对象的属性 一个 ref 会在作为响应式对象的属性被访问或修改时自动解包。换句话说,它的行为就像一个普通的属性:

const count = ref(0)
const state = reactive({count
})console.log(state.count) // 0state.count = 1
console.log(count.value) // 1
  1. 如果将一个新的 ref 赋值给一个关联了已有 ref 的属性,那么它会替换掉旧的 ref:

const otherCount = ref(2)state.count = otherCount
console.log(state.count) // 2
// 原始 ref 现在已经和 state.count 失去联系
console.log(count.value) // 1

只有当嵌套在一个深层响应式对象内时,才会发生 ref 解包。当其作为浅层响应式对象的属性被访问时不会解包。

数组和集合的注意事项

与 reactive 对象不同的是,当 ref 作为响应式数组或原生集合类型(如 Map) 中的元素被访问时,它不会被解包:

const books = reactive([ref('Vue 3 Guide')])
// 这里需要 .value
console.log(books[0].value)const map = reactive(new Map([['count', ref(0)]]))
// 这里需要 .value 访问
console.log(map.get('count').value)//输出0new Map([['count', ref(0)]] 这个理解起来就是
访问 key为count的对应value值 
也就是一组键值对的结构,具有极快的查找速度。

ref自动解包就是无需加上.value访问,比如在模版中使用会自动解包{{msg}}

不会自动解包 就是需要再后面加上一个.value才能访问到值

Map是ES6规范引入新的数据类型。

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

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

相关文章

js 中 复杂json 组装 实例通用模式

js 中 复杂json 组装 实例 目录概述需求&#xff1a; 设计思路实现思路分析1.js 中 复杂json 组装 实例2.js 中 复杂json 动态 组装 实例3.嵌套数组 参考资料和推荐阅读 ) Survive by day and develop by night. talk for import biz , show your perfect code,full busy&…

SpringBoot整合人大金仓数据库KingBase

1 去KingBase官网下载驱动jar包 2 将解压得到的所有jar包放置在libs目录下&#xff08;没有就新建一个目录&#xff09; 3 在pom文件添加相关依赖 <!--添加KingBase所需要的依赖--> <dependency><groupId>com.kingbase</groupId><artifactId>kin…

Stronghold Village

有了近2000个预制件和大量资产,您可以用基本的或先进的模块化预制件建造您的设防城镇或梦幻村庄,其中有许多定制选项和大量道具和物品 通过这个巨大的资源库,你可以创建村庄、城市、要塞、农村建筑、大教堂、城堡等。为你的环境提供高水平的细节,你可以创建外部装饰建筑,也…

普通人想通过抖音赚钱要先知道这4点

1.变现方式 想做抖音首先要想好变现路径以及通过什么方式变现。做抖音就是在经营某一类人群&#xff0c;因为人群绑定了精准标签&#xff0c;系统推送的精准又绑定了变现。所以要明确你经营的目标人群是谁&#xff0c;你在做谁的生意&#xff0c;你要赚谁的钱。他们的年龄、收…

UL2034详细介绍UL 安全单站和多站一氧化碳报警器标准

在介绍相关标准之前先介绍一下UL认证和UL测试报告的区别&#xff0c;检测认证行业6年老司机 UL认证是自愿性的认证&#xff0c;需要检测产品和审核工厂&#xff0c;每个季度审核一次&#xff0c;费用高、时间久&#xff0c;而且审厂非常的严格。 UL测试报告是根据产品选用相应…

Modbus协议学习第一篇之基础概念

什么是“协议” 大白话解释&#xff1a;协议是用来正确传递消息数据而设立的一种规则。传递消息的双方&#xff08;两台计算机&#xff09;在通信时遵循同一种协议&#xff0c;即可理解彼此传递的消息数据。 Modbus协议模型 Modbus协议模型较为简单&#xff0c;使用一种称为应用…

vue3dLoader Cannot read properties of null (reading ‘setCrossOrigin‘)“这个报错怎么解决?

默认情况下crossOrigin默认值是“anonymous” 如果出现报错的情况 请设置crossOrigin为空字符串即可。如&#xff1a; <vue3dLoader crossOrigin""> 相关阅读 推荐&#xff1a;vue-3d-loader支持.dae/.fbx/.gltf/.glb/.obj/.ply/.stl/.json&#xff0c;并支…

红酒和果酒推荐

一、红酒 首先&#xff0c;说一下大家常见的几十元红酒和贵的红酒的区别。 1.品牌价值。 2.工艺要求。 3.主要原料优质与否。几十元的红酒&#xff1a; 工艺要求没有高档红酒要求高&#xff0c;另外用的葡萄是榨的汁&#xff0c;品牌价值低&#xff08;目前市场品牌推广的费…

thinkphp6报错Driver [Think] not supported.

thinkphp6报错Driver [Think] not supported. 问题解决方法测试 问题 直接使用 View::fetch();渲染模板报错 解决方法 这个报错是由于有安装视图驱动造成的 运行如下命令安装即可 composer require topthink/think-view官方文档中是这么写的 视图功能由\think\View类配合视…

Eclipse插件UCdetector清理无用JAVA代码

下载插件 UCDetector - Browse /ucdetector at SourceForge.net 目前最新版本是2017年的2.0.0 保存 Eclipse/dropins 重启 操作 在项目上右键

DDNS-GO配置使用教程

环境&#xff1a;openwrt 下载地址&#xff1a;Releases jeessy2/ddns-go GitHub 下载 ssh至openwrt根目录&#xff0c;根据你的处理器选择要下载的版本&#xff0c;我是路由器&#xff0c;选择的是 ddns-go_5.7.1_linux_arm64.tar.gz wget github链接 安装 tar -zxvf…

如何在Spring Boot中使用EhCache缓存

1、EhCache介绍 在查询数据的时候&#xff0c;数据大多来自于数据库&#xff0c;我们会基于SQL语句与数据库交互&#xff0c;数据库一般会基于本地磁盘IO将数据读取到内存&#xff0c;返回给Java服务端&#xff0c;我们再将数据响应给前端&#xff0c;做数据展示。 但是MySQL…