Vue 3 第八章:Watch侦听器
文章目录
- Watch侦听器
- 1. 基础概念
- 1.1. Watch的基本用法
- 例子1:监听单个`ref`的值,直接监听
- 例子2:监听多个`ref`的值,采用数组形式
- 例子3:深度监听
- 例子4:监听`reactive`响应式对象单一属性,采用`回调函数`的形式
- 2. Watch的高级用法
- 2.1. immediate
- 2.2. deep
- 2.3. flush
- 3. Watch的性能优化
- 3.1. 使用computed代替watch
- 3.2. 使用throttle和debounce控制回调函数的执行频率
- 总结
Watch侦听器
在Vue3中,watch特性进行了一些改变和优化。与computed不同,watch通常用于监听数据的变化,并执行一些副作用,例如发送网络请求、更新DOM等。本文将介绍Vue3中watch特性。
1. 基础概念
1.1. Watch的基本用法
watch(source, callback, options?)
其中,source表示要监听的数据,可以是一个响应式的数据对象、一个计算属性或一个方法的返回值;callback表示当数据发生变化时要执行的回调函数;options表示watch的一些配置选项,例如immediate、deep、flush等。
例子1:监听单个ref的值,直接监听
<template><div><!-- 侦听单个变量 -->case1:<input v-model="userName" type="text"></div>
</template><script setup lang="ts">
import { ref, watch } from 'vue';const userName= ref<string>('张三');watch(userName, (newVal, oldVal) => {console.log(newVal, oldVal);
})
</script>
例子2:监听多个ref的值,采用数组形式
<template><div><!-- 侦听多个变量 -->case1:<input v-model="userName" type="text">case2:<input v-model="age" type="text"></div>
</template><script setup lang="ts">
import { ref, watch } from 'vue';const userName= ref<string>('张三');
const age= ref<number>(18);watch([userName, age], (newVal, oldVal) => {console.log(newVal, oldVal);
})
</script>
例子3:深度监听
- 如果用
ref实现深层次对象的响应式,侦听的时候需要开启深度侦听 - 用
reactive实现响应式,开启deep和不开启deep效果是一样的
<template><div><!-- 深度侦听 -->case1:<input v-model="obj.foo.bar.name" type="text"></div>
</template><script setup lang="ts">
import { reactive, watch } from 'vue';const obj = reactive({foo: {bar: {name: '张三'}}
})
watch(obj, (newVal, oldVal) => {console.log(newVal, oldVal);
}, {// deep: true, // 深度侦听, 监听ref创建的响应式对象必须开启
})
</script>
注意:此处监听的新值和旧值相同,主要是因为新旧值引用地址是相同的,此处可采取computed计算属性先实现深拷贝。示例如下:
import { reactive, watch, computed } from 'vue';const obj = reactive({foo: {bar: {name: '张三'}}
})let obj1 = reactive({})obj1 = computed(() => {return JSON.parse(JSON.stringify(obj))
})watch(obj1, (newVal, oldVal) => {console.log(newVal, oldVal);
})
例子4:监听reactive响应式对象单一属性,采用回调函数的形式
<template><div><!-- 侦听单一属性 -->case1:<input v-model="obj.foo.bar.name" type="text"></div>
</template><script setup lang="ts">
import { reactive, watch } from 'vue';const obj = reactive({foo: {bar: {name: '张三'}}
})
watch(() => obj.foo.bar.name, (newVal, oldVal) => {console.log(newVal, oldVal);}
)
</script>
2. Watch的高级用法
在Vue3中,watch特性进行了一些改变和优化。除了基本的watch用法外,还有一些高级用法可以使watch更加灵活和方便。下面是几个常用的高级用法:
2.1. immediate
immediate选项可以用于指定watch在组件创建时立即执行一次回调函数,而不必等待数据的变化。例如:
import { reactive, watch } from 'vue'const state = reactive({count: 0
})watch(() => state.count,(newVal, oldVal) => {console.log(`count值从${oldVal}变成了${newVal}`)},{ immediate: true }
)
在上面的例子中,我们使用immediate选项将watch的回调函数在组件创建时立即执行了一次,输出了初始值。当state.count变化时,watch的回调函数还会被再次执行。
2.2. deep
deep选项可以用于深度监听一个对象或数组的变化。当我们监听一个对象或数组时,默认情况下只会监听对象或数组的引用变化,而不会监听其内部数据的变化。如果我们需要深度监听对象或数组内部数据的变化,可以使用deep选项。例如:
import { reactive, watch } from 'vue'const state = reactive({todos: [{ id: 1, text: '学习Vue3', done: false },{ id: 2, text: '学习React', done: false },{ id: 3, text: '学习Angular', done: true }]
})watch(() => state.todos,(newVal, oldVal) => {console.log(`todos数组发生了变化`)},{ deep: true }
)state.todos[0].done = true // 输出:todos数组发生了变化
注意:当我们使用deep选项时,watch的性能会受到一定的影响,因为Vue需要对对象或数组进行递归遍历。因此,只有在必要的情况下才应该使用deep选项。
2.3. flush
flush选项可以用于指定watch的回调函数在何时执行。例如:
- sync:同步模式下执行
- pre:在数据变化之前执行回调函数
- post:在数据变化之后执行回调函数,但是需要等待所有依赖项都更新后才执行
import { reactive, watch } from 'vue'const state = reactive({count: 0
})watch(() => state.count,(newVal, oldVal) => {console.log(`count值从${oldVal}变成了${newVal}`)},{ flush: 'sync' }
)state.count++ // 输出:count值从0变成了1
在上面的例子中,我们使用flush选项将watch的回调函数在同步模式下执行了,这意味着watch的回调函数会在数据变化之后立即执行。当我们执行state.count++时,会触发count的变化,从而执行watch的回调函数并输出变化的值。
3. Watch的性能优化
在使用watch时,为了优化性能,我们可以采取以下一些方法:
3.1. 使用computed代替watch
在有些情况下,如果我们只是想监听一个值的变化,并在变化时执行一些操作,我们可以使用computed代替watch。computed可以自动缓存计算的结果,只有在它的依赖项变化时才会重新计算,因此可以提高一定的性能。例如:
import { reactive, computed } from 'vue'const state = reactive({count: 0
})const doubleCount = computed(() => {return state.count * 2
})console.log(doubleCount.value) // 输出:0state.count++console.log(doubleCount.value) // 输出:2
3.2. 使用throttle和debounce控制回调函数的执行频率
在有些情况下,我们可能会频繁地监听一个值的变化,并在变化时执行一些操作。如果回调函数执行的太频繁,会影响性能。为了避免这种情况,我们可以使用throttle和debounce控制回调函数的执行频率。
throttle和debounce都是用于控制函数执行频率的工具函数。throttle可以用于控制函数在一定时间内只能执行一次,而debounce可以用于控制函数在一定时间内不会连续执行。例如:
import { reactive, watch } from 'vue'
import { throttle } from 'lodash-es'const state = reactive({count: 0
})watch(() => state.count,throttle((newVal, oldVal) => {console.log(`count值从${oldVal}变成了${newVal}`)}, 1000)
)state.count++
总结
watch特性是Vue中非常重要的一个特性,通过学习watch的基础概念、高级用法、实战应用和性能优化方法,可以帮助我们更好地理解和应用Vue。
相关文章:
Vue 3 第八章:Watch侦听器
文章目录Watch侦听器1. 基础概念1.1. Watch的基本用法例子1:监听单个ref的值,直接监听例子2:监听多个ref的值,采用数组形式例子3:深度监听例子4:监听reactive响应式对象单一属性,采用回调函数的…...
GlassFish的安装与使用
一、产品下载与安装glassfish下载地址:https://download.oracle.com/glassfish/5.0.1/release/index.html下载后解压即完成安装,主要目录说明:bin目录:为asadmin命令所在目录。glassfish为主目录:glassfish\bin目录为命…...
【java】Java 重写(Override)与重载(Overload)
文章目录重写(Override)方法的重写规则Super 关键字的使用重载(Overload)重载规则实例重写与重载之间的区别总结重写(Override) 重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写! 重写的好处在于…...
OpenCV-PyQT项目实战(12)项目案例08:多线程视频播放
欢迎关注『OpenCV-PyQT项目实战 Youcans』系列,持续更新中 OpenCV-PyQT项目实战(1)安装与环境配置 OpenCV-PyQT项目实战(2)QtDesigner 和 PyUIC 快速入门 OpenCV-PyQT项目实战(3)信号与槽机制 …...
面向对象设计模式:结构型模式之装饰器模式
文章目录一、引入二、装饰器模式2.1 Intent 意图2.2 Applicability 适用性2.3 类图2.4 优缺点2.5 应用实例:Java IO 类2.6 应用实例:咖啡馆订购系统一、引入 咖啡馆订购系统 Initial 初始 4 种咖啡 House blend (混合咖啡)Dark Roast (深度烘培)Decaf (…...
Unity iOS 无服务器做一个排行榜 GameCenter
排行榜需求解决方案一(嗯目前只有一)UnityEngine.SocialPlatformsiOS GameCenterAppStoreConnect配置Unity 调用(如果使用GameCenter系统的面板,看到这里就可以了)坑(需要获取数据做自定义面板的看这里)iOS代码Unity 代码吐槽需求 需求:接入…...
现在招个会自动化测试的人是真难呀~你会个锤子的自动化测试
现在招个会自动化测试的人是真难呀~ 前一段时间公司计划要招2个自动化测试到岗,同事面试了十几个来应聘的人,发现一个很奇怪的现象,在面试的时候,如果问的是框架API、脚本编写这些问题,基本上所有人都能对答如流&…...
OracleDatabase——数据库表空间dmp导出与导入
由于公司的程序一直部署在客户现场内网,内网调试难度高,一般是有备份还原数据库的需求,这里简记备份(导出)数据库dmp文件与恢复(导入)的步骤。 一、导出dmp文件 exp与expdp命令异同 相同点&a…...
20张图带你彻底了解ReentrantLock加锁解锁的原理
哈喽大家好,我是阿Q。 最近是上班忙项目,下班带娃,忙的不可开交,连摸鱼的时间都没有了。今天趁假期用图解的方式从源码角度给大家说一下ReentrantLock加锁解锁的全过程。系好安全带,发车了。 简单使用 在聊它的源码…...
Dockerfile构建Springboot镜像
Dockerfile构建Springboot镜像 文章目录 Dockerfile构建Springboot镜像 简介实例演示 前期准备 Docker环境Springboot项目Dockerfile文件 Windows 要求构建镜像启动测试 Linux 要求构建镜像启动测试 简介 容器技术大流行的时代,也是docker大流行的时代。 此文…...
从深分页查询到覆盖索引
最近看到一道面试题,如何优化深分页查询 最简单的例子是 select * from web_bill_main limit 30000,10;分页达到30000行,需要把前面29999行都过滤掉,才能找到这10条数据 所以整体时间花了80ms(工具显示时间) 我当时的第一反应是࿰…...
Go语言学习的第三天--下部分(Gin框架的基础了解)
每天都会分享Go的知识,喜欢的朋友关注一下。每天的学习分成两部分基础(必要的,基础不牢地动山摇),另一部分是Go的一些框架知识(会不定时发布,因为小Wei也是一名搬砖人)。但是可以保证…...
JDK的动态代理(powernode 文档)(内含源代码)
JDK的动态代理(powernode 文档)(内含源代码) 源代码下载链接地址:https://download.csdn.net/download/weixin_46411355/87546086 一、动态代理 目录JDK的动态代理(powernode 文档)࿰…...
第1章 多线程基础
第1章 多线程基础 1.1.2 线程与进程的关系 进程可以看成是线程的容器,而线程又可以看成是进程中的执行路径。 1.2 多线程启动 线程有两种启动方式:实现Runnable接口;继承Thread类并重写run()方法。 执行进程中的任务时才会产生线程&a…...
Linux基本指令(一)
文章目录文件操作文档操作系统管理网络通信备份压缩Ctrl Alt T 打开终端 文件操作 1.复制文件 cp afile bfile (将名为afile的文件复制到名为bfile的文件夹中,如果bfile文件不存在,系统将会创建此文件,如果bfile文件已经存在&a…...
el-dialog子组件在mounted周期内获取不到dom?
el-dialog子组件在mounted周期内获取不到dom?一、问题描述二、分析原因三、猜测正常父子组件在mounted生命周期内可以获得dom 父created—子created—子mounted—父mounted----子updated—父updated 一、问题描述 ** el-dialog控制显示隐藏是css控制的display&…...
第九章 opengl之光照(光照贴图)
OpenGL光照贴图漫反射贴图镜面光贴图光照贴图 一个物体的不同部分是不同的材质,那么会有不同的环境光和漫反射颜色表现。 漫反射贴图 原理就是:纹理。 是对同样的原理使用了不同的名字:其实都是使用一张覆盖物体的图像,让我们能…...
JDK动态代理(powernode CD2207 video)(内含教学视频+源代码)
JDK动态代理(powernode CD2207 video)(内含教学视频源代码) 教学视频原代码下载链接地址:https://download.csdn.net/download/weixin_46411355/87545977 目录JDK动态代理(powernode CD2207 video…...
【Linux】Sudo的隐晦bug引发的一次业务问题排查
Sudo的隐晦bug引发的一次业务问题排查写在前面问题描述问题排查高负载现象排查日志排查跟踪任务调度过程Sudo引发的问题手动复现问题分析处理方案写在前面 记录一次生产环境sudo启动进程频繁被Kill且不报错的异常处理过程,如果遇到同样的问题只想要解决方案&#x…...
Java VisualVM 安装 Visual GC 插件图文教程
文章目录1. 通过运行打开 Java VisualVM 监控工具2. 菜单栏初始视图说明3. 工具插件菜单说明4. 手工安装插件5. 重启监控工具查看 Visual GC1. 通过运行打开 Java VisualVM 监控工具 首先确保已安装 Java 环境,如此处安装版本 JDK 1.8.0_161 C:\Users\niaonao>j…...
Doris从入门到上天系列第六篇:Doris中修改表的操作
一:修改表使用 ALTER TABLE 命令可以对表进行修改,包括 partition 、rollup、schemachange、rename 和 index 五种。语法:ALTER TABLE [database.]table alter_clause1[, alter_clause2, ...];alter_clause 分为 partition 、rollup、schema …...
OpCore Simplify:零基础黑苹果配置的智能助手
OpCore Simplify:零基础黑苹果配置的智能助手 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 对于许多电脑爱好者来说,安装黑苹…...
便携激光云高仪:精确测量云底高度、云层厚度等关键参数
便携激光云高仪是一种用于测量云层高度、厚度及分布情况的气象观测设备,广泛应用于气象监测、航空安全、环境研究等领域。其便携式设计特别适合野外作业和临时观测需求。设备通过激光脉冲探测云底高度,并实时分析云层垂直结构,为气象预报、灾…...
AI结对编程:借助快马平台智能生成qclaw官网的AI功能模块
最近在开发qclaw官网时,尝试用AI辅助完成了一个合同条款分析功能,整个过程比想象中顺畅很多。这个功能的核心是让用户输入合同文本后,自动评估风险等级并给出提示。下面分享下具体实现思路和与AI协作的实践经验。 功能设计要点 首先明确这个…...
STM32智能婴儿床系统设计与实现
基于STM32的智能婴儿床系统设计1. 项目概述1.1 系统架构本智能婴儿床系统采用模块化设计架构,以STM32F103RCT6微控制器为核心处理单元,集成多种传感器模块和执行机构。系统通过蓝牙与手机APP建立双向通信,实现环境参数监测、异常报警和远程控…...
ae新手福音,用快马平台ai生成带注释的片段视频代码轻松入门
作为一个刚接触AE的新手,第一次打开软件时确实被复杂的界面吓到了。各种面板、时间轴、效果控件看得眼花缭乱,更别说要自己写表达式了。直到发现了InsCode(快马)平台,用自然语言描述就能生成带详细注释的AE项目代码,简直是新手的救…...
Spring PetClinic实战解析:从单体应用到云原生部署的5大架构亮点
Spring PetClinic实战解析:从单体应用到云原生部署的5大架构亮点 【免费下载链接】spring-petclinic A sample Spring-based application 项目地址: https://gitcode.com/gh_mirrors/sp/spring-petclinic 你是否遇到过这样的困境:在学习Spring框架…...
JPEGCamera嵌入式库:LS-Y201摄像头UART协议解析与蓝牙传输
1. JPEGCamera 库概述:面向 LS-Y201 模块的嵌入式 JPEG 图像采集与蓝牙传输框架JPEGCamera 是一个专为 LinkSprite LS-Y201 JPEG 摄像头模块设计的轻量级嵌入式软件库,其核心目标是在资源受限的 MCU 平台上(如 STM32F1/F4 系列、ESP32、nRF52…...
你的爬虫被识别了?可能是浏览器指纹惹的祸!教你用Playwright伪装Canvas/WebGL指纹
浏览器指纹识别:爬虫工程师的终极伪装术 当你的爬虫程序已经完美解决了User-Agent轮换、IP代理池和请求频率控制,却依然被目标网站精准识别并封禁时,你可能正面临着现代反爬技术的终极挑战——浏览器指纹识别。这种技术不依赖于传统的请求特征…...
5个高效能技巧:人工智能术语库全场景应用从入门到精通
5个高效能技巧:人工智能术语库全场景应用从入门到精通 【免费下载链接】Artificial-Intelligence-Terminology-Database 这个仓库包含一个关于人工智能术语的数据库。适合AI研究者、学生以及希望了解AI专业术语的人士。特点是包含大量AI相关词汇,有助于理…...
