vue3中ref及reactive的说明

目录

1.响应式说明

2.vue3的ref及reactive的使用

3.reactive响应式失效问题

4.总结


1.响应式说明

vue的响应式是vue框架中的核心概念之一,它是指当数据发生变化时,vue能够自动更新视图。vue2的响应式是基于Object.defineProperty进行实现的。

当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用 Object.defineProperty 把这些 property 全部转为 getter/setter。Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。

这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更。这里需要注意的是不同浏览器在控制台打印数据对象时对 getter/setter 的格式化并不同,所以建议安装 vue-devtools 来获取对检查数据更加友好的用户界面。

每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。

vue3的响应式是通过ref及reactive来声明响应式状态。

当你在模板中使用了一个 ref,然后改变了这个 ref 的值时,Vue 会自动检测到这个变化,并且相应地更新 DOM。这是通过一个基于依赖追踪的响应式系统实现的。当一个组件首次渲染时,Vue 会追踪在渲染过程中使用的每一个 ref。然后,当一个 ref 被修改时,它会触发追踪它的组件的一次重新渲染。

在标准的 JavaScript 中,检测普通变量的访问或修改是行不通的。然而,我们可以通过 getter 和 setter 方法来拦截对象属性的 get 和 set 操作。

.value 属性给予了 Vue 一个机会来检测 ref 何时被访问或修改。在其内部,Vue 在它的 getter 中执行追踪,在它的 setter 中执行触发。

另一个 ref 的好处是,与普通变量不同,你可以将 ref 传递给函数,同时保留对最新值和响应式连接的访问。当将复杂的逻辑重构为可重用的代码时,这将非常有用。

当你修改了响应式状态时,DOM 会被自动更新。但是需要注意的是,DOM 更新不是同步的。Vue 会在“next tick”更新周期中缓冲所有状态的修改,以确保不管你进行了多少次状态修改,每个组件都只会被更新一次。

reactive() 将使对象本身具有响应性,响应式对象是 JavaScript 代理,其行为就和普通对象一样。不同的是,Vue 能够拦截对响应式对象所有属性的访问和修改,以便进行依赖追踪和触发更新。值得注意的是,reactive() 返回的是一个原始对象的 Proxy,它和原始对象是不相等的。只有代理对象是响应式的,更改原始对象不会触发更新。

2.vue3的ref及reactive的使用

①示例

<template><div id="count1">count值: {{ count }}</div><div><div>姓名:{{ student.name }}</div><div id="stu1">点赞数:{{ student.num }}</div></div><div><button @click="btnClick()">按钮</button></div>
</template>
<script setup>
// import {ref, reactive} from 'vue';
const ref = (target) => {let _value = target;return{get value() {return _value;},set value(newValue){_value = newValue;document.getElementById('count1').innerHTML = `count值: ${newValue}`;}}
}
const reactive = (target)=>{
return new Proxy(target,{get:(obj,key) =>{return obj[key];},set:(obj,key,newValue) =>{obj[key] = newValue;document.getElementById('stu1').innerHTML = `点赞数:${newValue}`;return true;}
})
}
const count = ref(0);
const student = reactive({name: '小李',num: 0
})const btnClick = () => {count.value++;student.num++;
}
</script>

②说明

上面是一个简单的模拟ref及reactive的实现的示例。

ref说明:

ref可以声明任何类型的变量,包含基本类型及复杂类型。ref() 接收参数,并将其包裹在一个带有 .value 属性的 ref 对象中返回。

在js代码中需要通过ref对象的.value属性,然后再得到具体的内容进行赋值和使用,在template中可以直接使用,不需要进行.value操作。

reactive说明:

reactive() 返回的是一个原始对象的 Proxy,只有代理对象是响应式的,更改原始对象不会触发更新。使用 Vue 的响应式系统的最佳实践是 仅使用你声明对象的代理版本

有限的值类型:它只能用于对象类型 (对象、数组和如 MapSet 这样的集合类型)。它不能持有如 stringnumberboolean 这样的原始类型。

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

对解构操作不友好:当我们将响应式对象的原始类型属性解构为本地变量时,或者将该属性传递给函数时,我们将丢失响应性连接。

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

3.reactive响应式失效问题

1.reactive声明对象没有失效

<template><div id="count1">count值: {{ count }}</div><div><div>姓名:{{ student.name }}</div><div id="stu1">点赞数:{{ student.num }}</div></div><div><button @click="btnClick()">按钮</button></div>
</template>
<script setup>
import { ref, reactive } from 'vue';
const count = ref(0);
let student = reactive({name: '小李',num: 0
})const btnClick = () => {count.value++;student = reactive({name: '小孙',num: 1})
}
</script>

点击按钮前:

点击按钮后:

可以看到值已经发生变化。

2.reactive声明数组响应式失效。

<template>
<div>{{ list }}
</div>
<div><button  @click="btnClick()">按钮</button>
</div></template><script setup>import {reactive} from 'vue';let list = reactive(['123','234','345'
])
const btnClick = () =>{list = ['258','369','147'];console.log(list);
}
</script>

按钮点击前:

按钮点击后:

点击按钮后,list的值如控制台已经发生了变化,但是视图已经渲染,但是内容没有更新。此种方式不会触发视图更新,因为地址指向变成了一个新的地址。

解决方法:

①使用ref进行定义。将对象的.value设定为新的数组。

②将数组用对象的方式进行包裹,给对象中的属性进行赋值,在template中使用对象中的属性进行显示。如下:

<template>
<div>{{ list.arr }}
</div>
<div><button  @click="btnClick()">按钮</button>
</div></template><script setup>import {ref,reactive} from 'vue';let list = reactive({arr:['123','234','345'
]
})
const btnClick = () =>{list.arr = ['258','369','147'];console.log(list);
}
</script>

③采用push方式进行更新,注意要使用扩展运算符,否则会在数组中嵌套一个数据。

<template><div>{{ list }}</div><div><button @click="btnClick()">按钮</button></div>
</template><script setup>import { ref, reactive } from 'vue';let list = reactive(['123', '234', '345'
]
)
const btnClick = () => {list.push(...['258', '369', '147']);console.log(list);
}
</script>

 在使用reactive时需要使用const方式进行定义。通过const定义只能修改对象中属性,而不能修改整个对象。

4.总结

关于ref及reactive的用法,还是要在开发中多多使用,遇到响应式失效问题,仔细研究,加强理解。

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

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

相关文章

WebLangChain_ChatGLM:结合 WebLangChain 和 ChatGLM3 的中文 RAG 系统

WebLangChain_ChatGLM 介绍 本文将详细介绍基于网络检索信息的检索增强生成系统&#xff0c;即 WebLangChain。通过整合 LangChain&#xff0c;成功将大型语言模型与最受欢迎的外部知识库之一——互联网紧密结合。鉴于中文社区中大型语言模型的蓬勃发展&#xff0c;有许多可供利…

windows下使用logstash同步跨网络集群的数据

我们在开发环境过程中&#xff0c;可能会遇到这样的场景。我们可以通过VPN访问远端的机房。有可能还要跨机房访问。这篇文章演示使用logstash&#xff0c;在windows上&#xff0c;去同步跨网络环境的不同机房之间的数据。 此方式受网络限制。适合同步小规模数据。 下载logstash…

C# DotNetCore AOP简单实现

背景 实际开发中业务和日志尽量不要相互干扰嵌套&#xff0c;否则很难维护和调试。 示例 using System.Reflection;namespace CSharpLearn {internal class Program{static void Main(){int age 25;string name "bingling";Person person new(age, name);Conso…

Android Studio好用的插件推荐

目录 一、插件推荐 二、如何下载 1.点击File—>Settings ​2.点击Plugins然后进行搜索下载 三、Android Studio 模板 一、插件推荐 这个插件可以为您自动生成Parcelable代码。Parcelable是一种用于在Android组件之间传递自定义对象的机制&#xff0c;但手动编写Parcela…

dcoker-compose一键部署EFAK —— 筑梦之路

简介 EFAK&#xff08;Eagle For Apache Kafka&#xff0c;以前称为 Kafka Eagle&#xff09;是一款由国内公司开源的Kafka集群监控系统&#xff0c;可以用来监视kafka集群的broker状态、Topic信息、IO、内存、consumer线程、偏移量等信息&#xff0c;并进行可视化图表展示。独…

力扣刷题-二叉树-路径总和

112 路径总和 给定一个二叉树和一个目标和&#xff0c;判断该树中是否存在根节点到叶子节点的路径&#xff0c;这条路径上所有节点值相加等于目标和。 说明: 叶子节点是指没有子节点的节点。 示例: 给定如下二叉树&#xff0c;以及目标和 sum 22&#xff0c; 返回 true, 因为…

如何将数据库导入MySQL的办法

在电脑cmd终端进行导入 首先找到MySQL中bin的位置 第一步&#xff1a;找到MySQL 第二步&#xff1a;进入MySQL 第三步&#xff1a;打开bin 第四步&#xff1a;输入cmd进入终端 第五步&#xff1a; 输入mysql -uroot -p 然后会弹出enter password&#xff1a; 输入你的密码…

记一次挖矿病毒的溯源

ps&#xff1a;因为项目保密的原因部分的截图是自己在本地的环境复现。 1. 起因 客户打电话过来说&#xff0c;公司web服务异常卡顿。起初以为是web服务缓存过多导致&#xff0c;重启几次无果后觉得可能是受到了攻击。起初以为是ddos攻击&#xff0c;然后去查看web服务器管理…

基于ssm日用品网站设计论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本日用品网站就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&…

数字孪生项目的开发平台

WEBGL 开发数字孪生项目的流程涵盖了需求分析、场景搭建、模型创建、数据接入、动画与交互、性能优化、测试与部署以及维护与升级等方面。WEBGL 开发数字孪生项目的流程可以分为以下几个步骤&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外…

SCI一区级 | Matlab实现GWO-CNN-GRU-selfAttention多变量多步时间序列预测

SCI一区级 | Matlab实现GWO-CNN-GRU-selfAttention多变量多步时间序列预测 目录 SCI一区级 | Matlab实现GWO-CNN-GRU-selfAttention多变量多步时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现GWO-CNN-GRU-selfAttention灰狼算法优化卷积门控循环…

ubuntu debian mini安装系统 有线选项消失或ens33 ethernet 未托管解决方法

nmcli device status#修改NetworkManager.conf如下 sed s/false/true/ /etc/NetworkManager/NetworkManager.confsed -i s/false/true/ /etc/NetworkManager/NetworkManager.conf#重启生效systemctl restart NetworkManager