vue3中的ref与reactive

server/2024/12/22 17:42:46/

摘要

在vue3直接定义变量不是响应式数据

在vue3中定义变量更改变量页面是显示不出来的

在按钮中绑定一个函数,当我点击它的时候发生改变str值

点击前

点击后

点击后控制台显示更改数据,而页面中不显示数据,这就是vue3没触发响应式

使用ref和reactive可以完美结局,以下文章讲述如何使用ref和reactive来进行响应式操作

一、ref

ref是一个函数,是vue组合式api中的一个方法,主要作用就是定义一个响应式的数据、

<template><div><p>{{ msg }}</p><button @click="handleClick">更新数据</button></div>
</template><script lang="ts" setup>import { ref } from 'vue';// 定义变量
let msg: any = ref("你好世界")
// 绑定点击事件
let handleClick = () => {console.log(msg);}</script>

当我们点击更新变量得到是是一个ref对象

更改值操作-----------------------------(页面同步)

我们要获取value值,这样才能响应式

<template><div><p>{{ msg }}</p><button @click="handleClick">更新数据</button></div>
</template><script lang="ts" setup>import { ref } from 'vue';// 定义变量
let msg: any = ref("你好世界")
// 绑定点击事件
let handleClick = () => {// 修改数据必须加上value,因为被ref包裹的变量是一个ref对象msg.value = "你好地球"console.log(msg.value, ".value方法")}</script>

当我再次点击更新数据

直接发生响应式变化

l另外补充

    // unref可以直接提取ref定义的value值console.log(unref(msg), "unref方法")// isRef判断是不是一个ref定义的数据,是就返回true不是就返回falseconsole.log(isRef(msg), "isRef方法")

以后使用ref尽量使用.value

二、reactive

*reactive定义多个数据的响应式,返回的是一个proxy代理对象,被代理的对象叫做目标对象

reactive内部是通过es6的proxy实现的,通过代理对象将目标对象转为响应式数据

<template><div><p>名字:{{ msg.name }}<br>年龄:{{ msg.age }}<br>性别:{{ msg.sex }}</p><button @click="handleClick">更新数据</button></div>
</template><script lang="ts" setup>import { ref, reactive } from 'vue';// 定义变量
let msg: any = reactive({name: "张三",age: 20,sex: "男"
})
// 绑定点击事件
let handleClick = () => {console.log(msg, 'proxy代理对象')}</script>

页面输出

更改值操作-----------------------------(页面同步)

<template><div><p>名字:{{ msg.name }}<br>年龄:{{ msg.age }}<br>性别:{{ msg.sex }}<br>爱好:{{ msg.pin }}</p><button @click="handleClick">更新数据</button></div>
</template><script lang="ts" setup>import { ref, reactive } from 'vue';// 定义变量
let msg: any = reactive({name: "张三",age: 20,sex: "男",})
// 绑定点击事件
let handleClick = () => {msg.name = "李四"//在vue2中不先定义直接添加属性会导致视图不更新,解决办法this.$set//  在vue3中使用reactive可以msg.pin = "健身"console.log(msg, 'proxy代理对象')}</script>

使用reactive可以直接修改数据而且可以添加没定义的数据

三、ref与reactive区别?

1、ref区别

通过ref定义的基本数据类型

<template><div><p>{{ m1 }}</p><button @click="handleClick">更新数据</button></div>
</template><script lang="ts" setup>import { ref, reactive } from 'vue';// 定义变量
// 通过ref定义的基本数据类型
let m1 = ref("我是张三");// 绑定点击事件
let handleClick = () => {// 只要通过ref定义的基本数据类型,是一个ref对象,修改数据必须加上.valuem1.value = "我是李四";
}</script>

通过ref定义的复杂数据类型

<template><div><p>{{ m2.wifi.title }}</p><button @click="handleClick">更新数据</button></div>
</template><script lang="ts" setup>import { ref, reactive } from 'vue';// 定义变量
// 通过ref定义的复杂的数据类型
let m2 = ref({name: "小鸟",wifi: {title: "苹果",},
});// 绑定点击事件
let handleClick = () => {// 只要通过ref定义的复杂数据类型,是一个ref对象,只是内部会自动变成reactive代理对象的形式m2.value.wifi.title = "香蕉";console.log(m2);}</script>

2、reactive区别

reactive不能定义基本数据类型,只能定义复杂的数据类型

<template><div><p>{{ m3.wifi.title }}</p><button @click="handleClick">更新数据</button></div>
</template><script lang="ts" setup>import { ref, reactive } from 'vue';// 定义变量
// 通过reactive定义的复杂的数据类型,注意reactive不能定义基本数据类型
let m3 = reactive({name: "猴子",wifi: {title: "香蕉",},
});// 绑定点击事件
let handleClick = () => {// 只要通过reactive定义的复杂的数据类型,是一个proxy代理对象m3.name = "蜜蜂";m3.wifi.title = "糖水";console.log(m3);}</script>

3、reactive小问题

reactive弊端:赋值一一对应赋值页面可以响应式,页面更新

而整体赋值页面会渲染不上,只有控制台会有变化,而页面中无法更新

将数据obj对象可以直接赋值给reactive定义的m3中,但是不是响应式的(ref是可以的)

ref可以这样整体赋值,但是到后面得加.value

reactive整体赋值解决方法

方法一

创建这个arr[]对象可以是空对象!!

方法二

使用****Object.assign(原数据, 新数据)、

对象中添加多个新属性,则通过 **Object.assign(原数据, 新数据)**创建新对象

Object.assign(m3, obj)

方法三

使用forEach

使用forEach必须是数组形式

总结

ref和reactive是vue3组合式api中最重要的响应式api

ref是用来处理基本数据类型,reactive是用来处理复杂的数据类型

如果用ref处理复杂的数据类型,那么内部会自动将复杂的数据类型转为reactive代理对象的形式

ref内部:通过value属性添加getter,setter来实现数据的响应式

reactive内部:通过es6中的proxy来实现对对象内部所有的数据进行劫持

注意:ref定义的数据修改数据的时候需要加上.value,reactive不需要


http://www.ppmy.cn/server/152281.html

相关文章

mac 安装graalvm

Download GraalVM 上面链接选择jdk的版本 以及系统的环境下载graalvm的tar包 解压tar包 tar -xzf graalvm-jdk-<version>_macos-<architecture>.tar.gz 移入java的文件夹目录 sudo mv graalvm-jdk-<version> /Library/Java/JavaVirtualMachines 设置环境变…

Leetcode 串联所有单词的子串

算法思想&#xff08;中文解释&#xff09; 这道题目要求我们在字符串 s 中找到所有子串&#xff0c;这些子串是字符串数组 words 中所有单词的串联&#xff0c;并且每个单词只能使用一次&#xff0c;且顺序可以任意。下面是代码的算法思想&#xff1a; 1. 核心思路 分解问题…

三、使用langchain搭建RAG:金融问答机器人--检索增强生成

经过前面2节数据准备后&#xff0c;现在来构建检索 加载向量数据库 from langchain.vectorstores import Chroma from langchain_huggingface import HuggingFaceEmbeddings import os# 定义 Embeddings embeddings HuggingFaceEmbeddings(model_name"m3e-base")#…

信息安全管理与评估赛题第4套

全国职业院校技能大赛 高等职业教育组 信息安全管理与评估 赛题四 模块一 网络平台搭建与设备安全防护 1 赛项时间 共计180分钟。 2 赛项信息 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 第一阶段 网络平台搭建与设备安全防护 任务1 网络平台搭建 XX:XX- XX:XX 50 任务2…

视频点播系统|Java|SSM|VUE| 前后端分离

【技术栈】 1⃣️&#xff1a;架构: B/S、MVC 2⃣️&#xff1a;系统环境&#xff1a;Windowsh/Mac 3⃣️&#xff1a;开发环境&#xff1a;IDEA、JDK1.8、Maven、Mysql5.7 4⃣️&#xff1a;技术栈&#xff1a;Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html 5⃣️数据库可…

uni-app开发商品分类页面实现

目录 一:功能概述 二:功能实现 一:功能概述 这里商品分类按照常规的分类页面样式设计,左侧为一级分类,右侧为二级分类。在左侧切换不同的一级分类可以修改右侧的二级分类数据。右侧的展现方式是最上面显示对应的一级分类logo图片,下面展示二级分类的logo和名称。 二:…

SpringBoot 3.4.x踩坑记录及解决方案(持续更新)

废话 最近使用JDK17Spring Boot3.4.0 做新项目遇到的一些坑&#xff0c;记录并且给出一些实际的解决方案 一、集成Mybatis Plus 3.5.9的问题 第一&#xff1a;不能只引入mybatis-plus-spring-boot3-starter依赖了&#xff0c;需要配合mybatis-plus-jsqlparser <dependenc…

实验13 C语言连接和操作MySQL数据库

一、安装MySQL 1、使用包管理器安装MySQL sudo apt update sudo apt install mysql-server2、启动MySQL服务&#xff1a; sudo systemctl start mysql3、检查MySQL服务状态&#xff1a; sudo systemctl status mysql二、安装MySQL开发库 sudo apt-get install libmysqlcli…