vue3 监听器,组合式API的watch用法

watch函数

在组合式 API 中,我们可以使用 watch 函数在每次响应式状态发生变化时触发回调函数

watch(ref,callback(newValue,oldValue),option:{})
ref:被监听的响应式量,可以是一个 ref (包括计算属性)、一个响应式对象、一个 getter 函数、或多个数据源组成的数组
callback:回调函数,当被监听的响应式量变化是触发回调,callback有两个参数,类型和ref一致,值是捕获到的变化后的ref,和变化前的ref
option: 对象提供一些监听函数的监听参数,比如是否开启深层监听

一个最简单的监听示例

<script setup>
import { ref, watch } from 'vue'const count = ref(0);watch(count, () => {console.log(count.value);
})</script><template><div><span>{{ count }}</span></div><button @click="count++">click</button>
</template>

当按钮点击时count递增,watch函数会捕获count的变化,并触发回调函数打印出count的值

这里 点击了20下每次变化都触发了一次回调

监听getter

<script setup>
import { ref,reactive, watch } from 'vue'const count = ref(0);
const obj = reactive({num:0});watch(count, (num) => {console.log("count=",num);
})watch(()=> obj.num , (num) => {console.log("sum=",num);
})</script><template><div><span>sum=</span><span>{{ count }}+</span><span>{{ obj.num }}</span></div><button @click="count++,obj.num++">click</button>
</template>

这里不能直接监听响应式对象的值(obj.sum ),而是需要用一个返回该属性的 getter 函数要监听的值( ()=> obj.sum ) 

深层监听器

深层侦听需要遍历被侦听对象中的所有嵌套的属性,对于一个对象来说,没有深度监听只有当整个对象改变才会被捕获,

虽然不能直接监听响应式对象的值,但是可以直接监听响应式对象,这会隐式的激活深层监听

  <div><span>sum=</span><span>{{ count }}+</span><span>{{ obj.num }}</span></div><button @click="count++,obj.num++">click</button>

const obj = reactive({num:0});watch( obj, (newValue,oldValue)=>{console.log(newValue,oldValue);
})

可以看出来回调的两个对象参数它们式相等的两个值,

当你监听对象内嵌套的对象时,则需要手动开启深层监听,否则只有当整个对象改变时才能被捕获

<div><span>sum=</span><span>{{ count }}+</span><span>{{ obj.num }}</span>
</div>
<button @click="count++,obj.num++,ob.obj.num++">click</button>
<span>嵌套对象的属性{{ ob.obj.num }}</span>
const ob = ref({obj:{num:0,str:"hello"},count:0
})watch(()=>ob.value.obj, (newValue,oldValue)=>{console.log(newValue,oldValue);
},{deep:true
})

 可以看到开启深层监听后就可以捕获到变化响应了

立刻回调和一次回调

{deep:true,immediate:true,once:true
}

除了深层回调还有两个参数,immediate,once,布尔值,它们分别表示,立刻执行一次回调(在开始捕获之前)和只回调一次(只捕获一次响应变化)

watchEffect函数

watchEffect会自动监听能访问到的且发生了响应变化的值,并且只跟踪回调中被使用到的属性,而不是递归地跟踪所有的属性,这有时候比深层监听遍历所有属性要更好,但是要注意,它仅会在其同步执行期间,才b捕获响应变化。在使用异步回调时,只有在第一个 await 正常工作前访问到的属性才会被捕获。

watchEffect(callback(newValue,oldValue),option:{})
callback:回调函数,当被监听的响应式量变化是触发回调,callback有两个参数,类型和ref一致,值是捕获到的变化后的ref,和变化前的ref
option: 对象提供一些监听函数的监听参数,

watch 和 watchEffect

watch 和 watchEffect 都能响应式地执行能响应的回调(触发页面变化)。它们之间的主要区别是追踪响应式依赖的方式:

watch:需要提供监听目标,监听属性更加精确,仅在监听的目标变化时触发

watchEffect: 不需要提供监听补码,监听时没有那么明确,自动追踪所有能访问到的(参与回调的)响应式属性。

<div :style="`background-color:${color}`"><span>sum=</span><span>{{ count }}+</span><span>{{ obj.num }}</span>
</div>
<button @click="count++,obj.num++,ob.obj.num++">click</button>
<button @click="color='green'">change</button>
<span>嵌套对象的属性{{ ob.obj.num }}</span>
watchEffect((newValue,oldValue)=>{console.log("捕获到了变化",count.value,"\n",newValue,oldValue);color.value = "red";
})

 回调中有count,当count变化时直接被捕获,改变了背景颜色,同时它还默认响应了一个函数

 回调触发时机

watchEffect(callback,option:{})option:flush:post/sync (指明post,则会在响应后回调,指明sync,则会在响应前回调)// 或者你可以用对应的函数;watchPostEffect()
watchSyncEffect()// 它们的效果是一样的

如果想在侦听器回调中能访问被 Vue 更新之后的所属组件的 DOM,你需要指明 flush: 'post' 或者使用 watchPostEffect()

如果想在侦听器回调在 Vue 进行任何更新之前触发:你需要指明 flush: 'sync' 或者使用 watchSyncEffect()

停止监听​

在 setup() 或 <script setup> 中,绝大部分的监听器会随着组件销毁而结束。

关键点是,监听器必须用同步语句创建,如果用异步回调创建一个监听器,那么它不会绑定到当前组件上,你必须手动停止它,以防内存泄漏。

手动停止一个侦听器,可以调用 watch 或 watchEffect 返回的函数

const unwatch = watchEffect(() => {})// ...当该侦听器不再需要时
unwatch()

执行这个返回的函数就可以结束监听,释放内存

代码总结

<script setup>
import { ref,reactive, watch,watchEffect } from 'vue'const count = ref(0);
const obj = reactive({num:0});
const color = ref("");
const ob = ref({obj:{num:0,str:"hello"},count:0
})watch(count, (num) => {console.log("count=",num);
})watch(()=> obj.num , (num) => {console.log("sum=",num);
})watch( obj, (newValue,oldValue)=>{console.log(newValue,oldValue);
})watch(()=>ob.value.obj, (newValue,oldValue)=>{console.log(newValue,oldValue);
},{deep:true,// immediate:true,// once:true
})watchEffect((newValue,oldValue)=>{console.log("捕获到了变化",count.value,"\n",newValue,oldValue);color.value = "red";
})
</script><template><div :style="`background-color:${color}`"><span>sum=</span><span>{{ count }}+</span><span>{{ obj.num }}</span></div><button @click="count++,obj.num++,ob.obj.num++">click</button><button @click="color='green'">change</button><span>嵌套对象的属性{{ ob.obj.num }}</span>
</template>

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

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

相关文章

STM32—按键控制LED(定时器)

目录 1 、 电路构成及原理图 2 、编写实现代码 main.c exit.c 3、代码讲解 4、烧录到开发板调试、验证代码 5、检验效果 此笔记基于朗峰 STM32F103 系列全集成开发板的记录。 1 、 电路构成及原理图 EXTI&#xff08;External interrupt/event controller&#xff…

查询SQL02:寻找用户推荐人

问题描述 找出那些 没有被 id 2 的客户 推荐 的客户的姓名。 以 任意顺序 返回结果表。 结果格式如下所示。 题目分析&#xff1a; 这题主要是要看这null值会不会用&#xff0c;如果说Java玩多了&#xff0c;你去写SQL时就会有问题。在SQL中判断是不是null值用的是is null或…

泛微开发修炼之旅--10基于Ecology实现附件上传,并将上传后的文件id存入表单附件控件中的示例及源码

文章链接&#xff1a;泛微开发修炼之旅--10基于Ecology实现附件上传&#xff0c;并将上传后的文件id存入表单附件控件中的示例及源码

tomcat10部署踩坑记录-公网IP和服务器系统IP搞混

1. 服务器基本条件 使用的阿里云服务器&#xff0c;镜像系统是Ubuntu16.04java version “17.0.11” 2024-04-16 LTS装的是tomcat10.1.24阿里云服务器安全组放行了&#xff1a;8080端口 服务器防火墙关闭&#xff1a; 监听情况和下图一样&#xff1a; tomcat正常启动&#xff…

MySQL进阶——索引使用规则

在上篇文章我们学习了MySQL进阶——索引&#xff0c;这篇文章学习MySQL进阶——索引使用规则。 索引使用规则 在使用索引时&#xff0c;需要遵守一些使用规则&#xff0c;否则索引会部分失效或全部失效。 最左前缀法则 最左前缀法则是查询从索引的最左列开始&#xff0c;并…

Vxe UI vxe-form 实现折叠表单,当表单很多时实现自动收起与展开

Vxe UI vue vxe-form 实现折叠表单&#xff0c;当表单很多时实现自动收起与展开 代码 folding 用于将当前表单项设置为默认隐藏 collapse-node 设置折叠按钮&#xff0c;加上之后会自动在该表单项的右侧显示一个折叠按钮 <template><div><vxe-formtitle-colo…

谷歌上架防关联,打包环境到底是不是关联因素之一?

在Google play上架应用&#xff0c;防关联是开发者们最关注的问题之一&#xff0c;只要开发者账号被谷歌审核系统与其它违规的开发者账号或应用存在关联&#xff0c;就很有可能被封号。 如果账号被封了&#xff0c;通常谷歌的封号通知邮件里只是写了因为关联或高风险、多次违规…

kafka-生产者拦截器(SpringBoot整合Kafka)

文章目录 1、生产者拦截器1.1、创建生产者拦截器1.2、KafkaTemplate配置生产者拦截器1.3、使用Java代码创建主题分区副本1.4、application.yml配置----v1版1.5、屏蔽 kafka debug 日志 logback.xml1.6、引入spring-kafka依赖1.7、控制台日志 1、生产者拦截器 1.1、创建生产者拦…

BeanDefinitionReader接口,Spring加载Bean的过程(非常流畅和容易理解)(Spring源码分析1)

一、前言 前言部分&#xff0c;介绍Spring框架的工作和大致原理&#xff0c;有基础的小伙伴可以跳过。 我们现在最常使用的开发框架SSM&#xff0c;分别是Spring、Spring MVC和Mybatis&#xff0c;其功能已经超出原生Spring非常多&#xff0c;所以想学习Spring原理&#xff0c;…

大漠插件7.2422

工具名称:大漠插件7.2422 /更新时间2024年6月2日 / v7.2422 1. 综合工具的图像编辑工具可以缩放窗口了 2. 增加AiFindPic AiFindPicEx AiFindPicMem AiFindPicMemEx AiEnableFindPicWindow 共5个接口 / 工具简介: 大漠 综合 插件 (dm.dll)采用vc6.0编写&#xff0c;识别速度超级…

Java 初识

Java 的发展历程 Sun 公司。 Oracle 公司。 普通版本&#xff0c;也叫过渡版本。 正式版本&#xff0c;也叫长期支持版本&#xff08;LTS&#xff09;。 Java SE&#xff0c;Java EE&#xff0c;Java ME Java 技术体系分为三个平台&#xff1a;Java SE&#xff0c;Java EE&a…

EasyExcel导出多个sheet封装

导出多个sheet 在需求中&#xff0c;会有需要导出多种sheet的情况&#xff0c;那么这里使用easyexcel进行整合 步骤 1、导入依赖 <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><d…

多尺度注意力创新

深度之眼17种多尺度注意力创新

西门子PLC学习之数据块的单个实例,多重实例与参数实例间的区别

首先介绍下函数&#xff0c;函数块与数据块这三个概念。 数据块 数据块里可以存储各种类型的参数。有人可能会问&#xff0c;m寄存器不是可以存储布尔值&#xff0c;8位&#xff0c;16位&#xff0c;32位变量吗&#xff0c;为什么要多此一举&#xff1f;因为虽然m寄存器能存储以…

​​​​​​​月薪20K的程序员应具备怎样的技能和水平?

在当今互联网高速发展的时代&#xff0c;程序员的薪资水平也在不断提高。对于月薪20K的程序员来说&#xff0c;他们不仅需要具备扎实的编程基础&#xff0c;还需要掌握一系列与工作相关的技能和能力。 月薪20K的程序员应具备怎样的技能和水平&#xff1f; 相信这是一个很多人都…

什么是智慧零售?智慧零售的发展前景如何?

在零售业的快速发展中&#xff0c;市场竞争日益激烈&#xff0c;产品同质化严重&#xff0c;线下销售与线上商店的竞争加剧&#xff0c;资金成本问题日益凸显。这些问题不仅限制了零售业的发展&#xff0c;也给消费者带来了诸多不便。然而&#xff0c;智慧零售的出现&#xff0…

ElementUI中date-picker组件,怎么把大写月份改为阿拉伯数字月份(例如:一月、二月,改为1月、2月)

要将 Element UI 的 <el-date-picker> 组件中的月份名称从中文大写&#xff08;如 "一月", "二月"&#xff09;更改为阿拉伯数字&#xff08;如 "1月", "2月"&#xff09;&#xff0c;需要进行一些定制化处理。可以通过国际化&a…

45-5 护网溯源 - 远控木马样本溯源

在分析恶意样本时&#xff0c;需要查看包括作者名字、ID、IP地址、域名等在内的相关信息。 把恶意样本上传到微步、360沙箱云分析&#xff1a;样本报告-微步在线云沙箱 (threatbook.com) 动态分析 运行截图 发现该木马是与一个装机软件绑定的&#xff0c;你运行正常软件的时候…

封装组件库仿elementui<1>

目录 type属性 引入字体图标 button的点击事件 disabled属性 methods:{//点击事件是外部注册的handleClick(e){this.$emit(click,e)//通知父组件点击了&#xff0c;点了按钮&#xff0c;触发外界的click&#xff1f;传参为事件对象//向父组件派发了click事件} }, type属性…

项目进度管理必备:15款最佳项目进度跟踪工具推荐

15好用的款主流项目进度管理软件&#xff1a;PingCode、Worktile、Trello、Tower、Asana、Smartsheet、Teambition、ClickUp、Wrike、Monday.com、Notion、禅道、飞书、云效、蓝凌。 严格的进度管理有助于更好地控制项目进展&#xff0c;提升团队效率&#xff0c;最终实现项目成…