【Vue】Vue3.0 (十二)、watch对ref定义的基本类型、对象类型;reactive定义的对象类型的监视使用

上篇文章:【Vue】Vue3.0(十一)Vue 3.0 中 computed 计算属性概念、使用及示例

🏡作者主页:点击!

🤖Vue专栏:点击!

⏰️创作时间:2024年10月16日12点45分

文章目录

    • 【watch】作用
    • 在`Vue3`中使用`watch`的时候,通常会遇到以下几种情况:
      • 情况一 监视`ref`定义的【基本类型】数据
      • 情况二 监视`ref`定义的【对象类型】数据
      • 情况三 监视`reactive`定义的【对象类型】数据
      • 情况四 监视`ref`或`reactive`定义的【对象类型】数据中的**某个属性*
      • * 情况五
    • 总结注意点:

【watch】作用

  • 作用:监视数据的变化(和Vue2中的watch作用一致)
  • 特点:Vue3中的watch只能监视以下四种数据
  1. ref定义的数据。
  2. reactive定义的数据。
  3. 函数返回一个值(getter函数)。
  4. 一个包含上述内容的数组。

Vue3中使用watch的时候,通常会遇到以下几种情况:

情况一 监视ref定义的【基本类型】数据

监视ref定义的【基本类型】数据:直接写数据名即可,监视的是其value值的改变。

<template><div class="person"><h1>情况一:监视【ref】定义的【基本类型】数据</h1><h2>当前求和为:{{sum}}</h2><button @click="changeSum">点我sum+1</button></div>
</template><script lang="ts" setup name="Person">import {ref,watch} from 'vue'// 数据let sum = ref(0)// 方法function changeSum(){sum.value += 1}// 监视,情况一:监视【ref】定义的【基本类型】数据const stopWatch = watch(sum,(newValue,oldValue)=>{console.log('sum变化了',newValue,oldValue)if(newValue >= 10){stopWatch()}})
</script>

情况二 监视ref定义的【对象类型】数据

监视ref定义的【对象类型】数据:直接写数据名,监视的是对象的【地址值】,若想监视对象内部的数据,要手动开启深度监视。

注意:

  • 若修改的是ref定义的对象中的属性,newValueoldValue 都是新值,因为它们是同一个对象。

  • 若修改整个ref定义的对象,newValue 是新值, oldValue 是旧值,因为不是同一个对象了。

代码:
使用ref定义对象类型数据:

<template><div class="person"><h2>情况2:watch监控ref定义的对象类型数据</h2><h2>姓名:{{person.name}}</h2><h2>年龄:{{person.age}}</h2><button @click="changeName">修改姓名</button><button @click="changeAge">修改年龄</button><button @click="changePerson">修改整个人</button></div>
</template><script lang="ts" setup name="Person">import { reactive, ref,computed ,watch} from 'vue'
//数据let person =ref({name:'张三',age:19})//方法function changeName(){person.value.name+='~';}function changeAge(){person.value.age+=1;}//修改整个人function changePerson(){person.value={name:'lis',age:20}; }//watch监视对象的时候,监视的是对象的地址值,并不关心对象内部的属性的值是否变化;如果想要监控对象内部的属性的值,//,需要手动开启内部监视//watch参数:第一个参数:监控的对象//watch参数:第二个参数:回调函数//watch参数:第三个参数:配置对象(deep、inmidiate等)watch(person,(newVal,oldVal)=>{console.log(newVal,oldVal);},{deep:true})
</script><style>
.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;
}li {font: 1em sans-serif;
}
</style>

情况三 监视reactive定义的【对象类型】数据

结论:监视reactive定义的【对象类型】数据,且默认开启了深度监视。
使用reactive定义对象类型数据

<template><div class="person"><h2>情况2:watch监控ref定义的对象类型数据</h2><h2>姓名:{{ person.name }}</h2><h2>年龄:{{ person.age }}</h2><button @click="changeName">修改姓名</button><button @click="changeAge">修改年龄</button><button @click="changePerson">修改整个人</button><hr /><h2>obj:{{ obj.a.b.c }}</h2><button @click="changeObj">修改OBJ</button></div>
</template><script lang="ts" setup name="Person">import { reactive, ref, computed, watch } from 'vue'
//数据
let person = reactive({name: '张三', age: 19
})let obj = reactive({a: {b: {c: 777}}
})
//方法
function changeName() {person.name += '~';
}
function changeAge() {person.age += 1;
}
//修改整个人
function changePerson() {Object.assign(person, { name: '李四', age: 99 });
}function changeObj() {obj.a.b.c = 222;
}
//监视,情况三:监视【reactive】定义的【对象类型】数据,且默认是开启深度监视的
watch(person, (newVal, oldVal) => {console.log('reactive定义的 person对象类型数据变化了', newVal, oldVal);
})//第二个监控函数
watch(obj,(newVal,oldVal)=>{console.log('reactive定义的 person对象类型数据变化了', newVal, oldVal);
})</script><style>
.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;
}li {font: 1em sans-serif;
}
</style>

情况四 监视refreactive定义的【对象类型】数据中的**某个属性*

监视refreactive定义的【对象类型】数据中的某个属性,注意点如下:

  1. 若该属性值不是【对象类型】,需要写成函数形式。
    在这里插入图片描述

代码:

<template><div class="person"><h2>情况4:watch监控ref定义的对象类型数据</h2><h3>姓名:{{person.name}} </h3><h3>年龄:{{person.age}} </h3><h3>汽车:{{person.car.c1}} /{{person.car.c2}} </h3><button @click="changeName">修改姓名</button><button @click="changeAge">修改年龄</button><button @click="changeC1">修改c1</button><button @click="changeC2">修改c2</button><button @click="changeCar">修改Car</button></div>
</template><script lang="ts" setup name="Person">import { reactive, ref, computed, watch } from 'vue'
//数据
let person=reactive({name:'张三',age:18,car:{c1:'宝马',c2:'奔驰'}
})function changeName(){person.name+='~';
}
function changeAge(){person.age+=1;
}
function changeC1(){person.car.c1='大众1'
}
function changeC2(){person.car.c2='大众2'}
function changeCar(){person.car={c1:'雅迪',c2:'艾玛'}
}//watch监控reactive定义的对象类型数据中的某个属性,且该属性是一个基本类型的数据,则该属性需要写成一个有返回值的函数
watch(()=>{return person.name},(newVal,oldVal)=>{console.log('person.name变化了',newVal,oldVal);
})</script><style>
.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;
}li {font: 1em sans-serif;
}
</style>

结果:(1)点击修改除了姓名以外的属性,触发不了监控,
在这里插入图片描述
(2)修改name属性,触发了监控中的输出
在这里插入图片描述

  1. 若该属性值是依然是【对象类型】,可直接编,也可写成函数,建议写成函数(这种的)
    验证代码:
<template><div class="person"><h2>情况4:watch监控ref定义的对象类型数据</h2><h3>姓名:{{person.name}} </h3><h3>年龄:{{person.age}} </h3><h3>汽车:{{person.car.c1}} /{{person.car.c2}} </h3><button @click="changeName">修改姓名</button><button @click="changeAge">修改年龄</button><button @click="changeC1">修改c1</button><button @click="changeC2">修改c2</button><button @click="changeCar">修改Car</button></div>
</template><script lang="ts" setup name="Person">import { reactive, ref, computed, watch } from 'vue'
//数据
let person=reactive({name:'张三',age:18,car:{c1:'宝马',c2:'奔驰'}
})function changeName(){person.name+='~';
}
function changeAge(){person.age+=1;
}
function changeC1(){person.car.c1='大众1'
}
function changeC2(){person.car.c2='大众2'}
function changeCar(){person.car={c1:'雅迪',c2:'艾玛'}
}//情况4、watch监控reactive定义的对象类型数据中的某个属性,且该属性是一个基本类型的数据,则该属性需要写成一个有返回值的函数
// watch(()=>{return person.name},(newVal,oldVal)=>{
//     console.log('person.name变化了',newVal,oldVal);
// })watch(()=>{return person.car},(newVal,oldVal)=>{console.log('person.car变化了',newVal,oldVal);
},{deep:true})</script><style>
.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;
}li {font: 1em sans-serif;
}
</style>

结果:

写法一:当写法是:

watch(()=>person.car,(newVal,oldVal)=>{console.log('person.car变化了',newVal,oldVal);
},{deep:true})

效果: 此时修改单个属性会被watch监视到,修改整个对象不会引起,

写法二、当写法是 : 监控的内容写成了对象的形式,此时函数返回的是地址,

watch(()=>{return person.car},(newVal,oldVal)=>{console.log('person.car变化了',newVal,oldVal);
})

效果: 此时修改单个属性不会被watch监控到,修改整个person.car对象,也就是地址变化才会被watch监视到。

写法三、当写法是:
相交于第二种写法,加了一个watch的参数,此时就既能监控到其中每个属性的变化,又能监控到整体的变化了。

watch(()=>{return person.car},(newVal,oldVal)=>{console.log('person.car变化了',newVal,oldVal);
},{deep:true})

效果: 单个属性和对象整体的变化都能引起watch函数的执行。

_结论:监视的要是对象里的属性,那么最好写函数式,注意点:若是对象监视的是地址值,需要关注对象内部,需要手动开启深度监视。

* 情况五

监视上述的多个数据

<template><div class="person"><h1>情况五:监视上述的多个数据</h1><h2>姓名:{{ person.name }}</h2><h2>年龄:{{ person.age }}</h2><h2>汽车:{{ person.car.c1 }}、{{ person.car.c2 }}</h2><button @click="changeName">修改名字</button><button @click="changeAge">修改年龄</button><button @click="changeC1">修改第一台车</button><button @click="changeC2">修改第二台车</button><button @click="changeCar">修改整个车</button></div>
</template><script lang="ts" setup name="Person">import {reactive,watch} from 'vue'// 数据let person = reactive({name:'张三',age:18,car:{c1:'奔驰',c2:'宝马'}})// 方法function changeName(){person.name += '~'}function changeAge(){person.age += 1}function changeC1(){person.car.c1 = '奥迪'}function changeC2(){person.car.c2 = '大众'}function changeCar(){person.car = {c1:'雅迪',c2:'爱玛'}}// 监视,情况五:监视上述的多个数据watch([()=>person.name,person.car],(newValue,oldValue)=>{console.log('person.car变化了',newValue,oldValue)},{deep:true})</script>

结果:修改name、car.c1、car.c2都能被watch监控到
在这里插入图片描述

总结注意点:

综合上面的内容:进行的总结

  • 1、ref定义的对象类型数据和reactive定义的对象类型数据,ref定义的对象数据,(let person =ref({ name:‘张三’,age:19 }) 已经定义了Person对象) 可以通过 person对象
    ={name:‘李四’,age:‘20’}这种的直接让Person这个变量的地址指向一个新的对象;直接改变了地址 而reactive定义的对象,不能通过person对象
    ={name:‘李四’,age:‘20’},因为不允许整个对象的修改,只允许里面某个属性的修改,如果非要对象中所有的属性都修改的话,就需要用到assign函数,第一个参数是要修改的老对象
    第二个参数是修改成新的对象是啥
  • 2、watch对于ref和reactive定义的对象类型数据,监控有什么区别呢?前者默认不开启深度监视,后者默认开始深度监视
  • 3、当响应对象是通过reactive对象定义的,那无论这个对象中的任何一个属性有变化,watch函数都能监控到。而且对reactive定义的对象的监听是隐式开启了
    深层监听,而且是关不掉的;
  • 4、ref定义的对象,在使用watch监视的时候,第二个参数中的返回值,会有时候是不同的,有时候是相同的,如果只是修改ref锁定义的对象中的一个属性,则newVal和OldVal是一样的,
    如果将一个新的对象给了ref定义的响应对象的value,那么此时Person指向的是一个新的对象的地址,相当于地址变了,此时newVal和oldVal是不一样的
    而对于reactive定义的响应类型的对象数据,无论变所有属性,还是单个属性,他的地址都是不变的,所以newVal和oldVal都是一样的;
  • 5、watch中的第一个参数,可以是普通对象、ref定义的对象、reactive定义的对象,或者由上面形成的数组

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

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

相关文章

施磊C++ | 进阶学习笔记 | 5.设计模式

五、设计模式 文章目录 五、设计模式1.设计模式三大类型概述一、创建型设计模式二、结构型设计模式三、行为型设计模式 2.设计模式三大原则3.单例模式1.饿汉单例模式2.懒汉单例模式 4.线程安全的懒汉单例模式1.锁双重判断2.简洁的线程安全懒汉单例模式 5.简单工厂(Simple Facto…

2024-10-15 学习人工智能的Day7

在简单的了解完学习人工智能所需的高数、线代、概率论后&#xff0c;我们又重新开始了国庆的学习&#xff0c;因为已经有十余天没有接触python&#xff0c;所以今天的内容主要是对之前学习的python的回顾与总结&#xff0c;然后对各个部分进行了简单的实践&#xff0c;在最后学…

【无线技术】Wireless Technologies and Techniques——Antenna and Propagation

一、 天线基础 Introduction to Antenna 天线&#xff08;Antenna&#xff09;是一种设备&#xff0c;用于将电信号转换为无线电波进行传输&#xff0c;反之亦然&#xff08;用于接收&#xff09;。天线是所有无线系统的 “ 眼睛和耳朵 ” &#xff0c;负责电磁波的发射和接收。…

性能测试工具JMeter

1. JMeter介绍 环境要求&#xff1a;要求java&#xff0c;jdk版本大于8&#xff1b; Apache JMeter 是 Apache 组织基于 Java 开发的压⼒测试⼯具&#xff0c;⽤于对软件做性能测试&#xff1b; 1.1 安装JMeter 1.下载tar包&#xff0c;解压即可。 解压完成后&#xff1a; 1.2…

查缺补漏----扩展操作码

变长操作码&#xff0c;即全部指令的操作码字段的位数不固定&#xff0c;且分散地放在指令字的不同位置上。最常见的变长操作码方法是扩展操作码&#xff0c;操作码的长度随地址码的减少而增加&#xff0c;不同地址数的指令可以具有不同长度的操作码&#xff0c;从而在满足需要…

AI 编译器学习笔记之七四 -- cann接口使用

1、安装昇腾依赖 # CANN发布件地址 https://cmc.rnd.huawei.com/cmcversion/index/releaseView?deltaId10274626629404288&isSelectSoftware&url_datarun Ascend-cann-toolkit_8.0.T15_linux-aarch64.run Ascend-cann-nnal_8.0.T15_linux-aarch64.run Ascend-cann-ker…

【机器学习】并行计算(parallel computation)Part2

Asynchronous Parallel Gradient Descent Using Parameter Server 用Parameter Server实现异步并行梯度下降 Parameter Server这种编程模型可以实现异步并行梯度下降&#xff0c;架构采用的是Client-Server&#xff0c;通信方式是Message-passing&#xff0c;同步方式是异步的…

阿里 C++面试,算法题没做出来,,,

我本人是非科班学 C 后端和嵌入式的。在我面试的过程中&#xff0c;竟然得到了阿里​ C 研发工程师的面试机会。因为&#xff0c;阿里主要是用 Java 比较多&#xff0c;C 的岗位比较少​&#xff0c;所以感觉这个机会还是挺难得的。 阿里 C 研发工程师面试考了我一道类似于快速…

2023年4月自考《数据库系统原理》04735试题

目录 一:选择题 二:填空题 三:设计题 四:简答题 五:综合题 一:选择题 1.在数据库系统中&#xff0c;专门用户建立和管理数据的软件是 (书中)P28页 A.DBS B.DB C.DBA D.DBMS 2.通常所说的数据库系统容不包括 (书中)P29页 A.应用程序 B.数据库管理员 C.用户 D.网络环境 …

MD5消息摘要算法学习

MD5&#xff08;Message Digest Algorithm 5&#xff09;是一种广泛使用的哈希函数&#xff0c;它用于生成128位的哈希值&#xff08;也称为消息摘要&#xff09;。MD5主要用于确保信息的完整性&#xff0c;即可以通过对数据生成的哈希值来验证数据是否被篡改。尽管MD5在过去被…

C嘎嘎入门篇:类和对象(3)

前言&#xff1a; 小编在写完了类和对象的1,2以后&#xff0c;下面紧接着开始类和对象3的学习&#xff0c;这一部分的知识是很重要的&#xff0c;各位读者朋友一定要好好的理解这篇文章&#xff0c;现在&#xff0c;代码时刻到。 目录 1.再探构造函数 前瞻 1.1.再探构造函数的特…

Python 基础的类型和操作符

Python特点 易于学习&#xff1a;Python有相对较少的关键字&#xff0c;结构简单&#xff0c;和一个明确定义的语法&#xff0c;学习起来更加简单。易于阅读&#xff1a;Python代码定义的更清晰。易于维护&#xff1a;Python的成功在于它的源代码是相当容易维护的。一个广泛的…

24.4 基于consul服务发现模式

本节重点介绍 : consul 安装consul go代码注册服务&#xff0c;注销服务&#xff0c;获取服务node_exporter改造为consul服务发现在数量比较大时&#xff0c;在注册服务的时候&#xff0c;关闭check&#xff0c;可以降低consul的压力 consul 安装 准备工作 # 下载consul wge…

软考24.10.15每日一练打卡 - 错题笔记

题目来源&#xff1a;https://ruankaodaren.com/ ##1. M公司将其开发的某软件产品注册商标为S&#xff0c;为确保公司在市场竞争中占据地位&#xff0c;M公司对员工进行了保密约束&#xff0c;此情形下&#xff0c;该公司不享有&#xff08; 商标权&#xff09;。 本题题干中提…

打造卓越APP体验:13款界面设计软件推荐

你知道如何选择正确的UI设计软件吗&#xff1f;你知道设计美观的用户界面&#xff0c;及带来良好用户体验的APP&#xff0c;需要什么界面设计软件吗&#xff1f;基于APP界面的功能不同&#xff0c;选择的APP界面设计软件也会有所不同。然而&#xff0c;并不是要把所有APP界面设…

低代码策略量化平台更新|大模型agents生态的一些思考

原创内容第680篇&#xff0c;专注量化投资、个人成长与财富自由。 用户判断星球会员后&#xff0c;会获得10个积分&#xff1a; 当其他用户发布策略&#xff0c;设置为下载需要积分时&#xff1a; 下载策略会扣除相应的积分&#xff0c;扣除的积分属于策略所有者。 策略运行结…

谈谈我的理解:引用计数 vs 可达性分析

前言 在学习垃圾回收机制时&#xff0c;首先需要了解如何判定哪些对象需要被回收&#xff0c;以及如何实现垃圾回收。本文将分享作者对两种常见的垃圾回收判断机制——引用计数法和可达性分析法——的理解与思考&#xff0c;旨在帮助读者更深入地理解这两种机制。 一、引用计数…

结合seata和2PC,简单聊聊seata源码

当前代码分析基于seata1.6.1 整体描述 整体代码流程可以描述为 TM开启全局事务&#xff0c;会调用TC来获取XID。TC在接收到通知后&#xff0c;会生成XID&#xff0c;然后会将当前全局事务保存到global_table表中&#xff0c;并且返回XID。在获取到XID后&#xff0c;会执行业务…

conda创建的新环境不干净!一定要注意!

总是出现明明是不同的环境&#xff0c;但是总是出现包交叉混用的问题&#xff0c;导致跑很多模型总是出现改了这个环境的包&#xff0c;那个环境又用不了了。就像下面这样&#xff0c;明明激活的是pyskl&#xff0c;安装mediapipe包显示在thwircamera中索引到就显示Requirement…

postgresql 安装

一、下载 PostgreSQL: File Browser 下载地址 PostgreSQL: File Browser 上传到服务器,并解压 二、安装依赖 yum install -y perl-ExtUtils-Embed readline-devel zlib-devel pam-devel libxml2-devel libxslt-devel openldap-devel 创建postgresql 和目录 useradd …