vue3【实用教程】侦听器 watch,自动侦听 watchEffect(),$watch,手动停止侦听器

watch

侦听明确指定的状态变化执行回调

实战场景

  • 侦听路由传参的变化,重新访问接口,刷新页面
  • 侦听接口返回值的变化,刷新页面

侦听值类型数据

// 选项式 API
watch: {// 每当 question 改变时,这个函数就会执行question(newQuestion, oldQuestion) {// 第一个参数是新值,第二个参数是旧值}
},
// 组合式 API
<script setup>import { ref, watch } from 'vue'let question = ref('')watch(question,(newQuestion, oldQuestion) => {// 第一个参数是新值,第二个参数是旧值})
</script>

侦听值类型的对象属性

// 选项式 API
watch: {// 监听对象person中gender属性的变化'person.gender':function(new_gender){},
},
// 组合式 API
watch(// 不能直接写 person.gender,会导致watch函数的第一个参数会得到一个字符串,不具有响应式,应改用返回对象属性的 getter 函数() => person.gender,(new_gender) => {}
)

侦听引用类型数据

选项式API需添加深度侦听 deep

watch选项默认是浅层监听,无法监听到嵌套属性的变化,所以监听对象时通常需要使用深度监听

// 选项式 API 
watch: {person: {// 在嵌套的属性变更时触发handler(newValue, oldValue) {// 因对象是引用类型的数据,对象属性发生变化时,对象引用的地址并没有发生变化,所以只要没有替换对象本身,这里的 `newValue` 和 `oldValue` 相同},// 开启深度监听deep: true}
}

注意事项
深度侦听需要遍历被侦听对象中的所有嵌套的属性,当用于大型数据结构时,开销很大。因此请只在必要时才使用它,并且要留意性能。

组合式API默认就是深度侦听

// 组合式 API 
let person = reactive({ age: 35 })watch(person,// 在嵌套的属性变更时触发(newValue, oldValue) => {// 因对象是引用类型的数据,对象属性发生变化时,对象引用的地址并没有发生变化,所以只要没有替换对象本身,这里的 `newValue` 和 `oldValue` 相同}
)

返回响应式对象的 getter 函数,只在返回不同的对象时触发回调:

watch(() => state.someObject,() => {// 仅当 state.someObject 被替换时触发}
)

通过 deep 选项,可强制转成深层侦听器

watch(() => state.someObject,(newValue, oldValue) => {// 此处`newValue` 和 `oldValue` 是相等的,除非 state.someObject 被整个替换},{ deep: true }
)

注意事项
深度侦听需要遍历被侦听对象中的所有嵌套的属性,当用于大型数据结构时,开销很大。因此请只在必要时才使用它,并且要留意性能。

侦听多个数据

// 选项式 API
watch: {x(newX,oldX) {},'y.value':function(newY) {},
},
// 选项式 API
watch([x, () => y.value], ([newX, newY]) => {
})

watch 函数的第一个参数可以是一个 ref (包括计算属性)、一个响应式对象、一个 getter 函数、或多个数据源组成的数组。

立即侦听 immediate

watch 默认是懒执行的:仅当数据源变化时,才会执行回调。
但有时需要在侦听器被创建时就触发监听

// 选项式 API
watch: {question: {handler(newValue, oldValue) {// 在组件实例创建时会立即执行(在 created 钩子之前执行,此时 data、computed 和 methods 选项都是可用的)},// 开启立即监听immediate: true}
}
// 组合式 API
watch(question,(newValue, oldValue) => {// 在组件实例创建时会立即执行(在 created 钩子之前执行,此时 data、computed 和 methods 选项都是可用的)},// 开启立即监听{ immediate: true }
)

单次侦听 once

vue3.4以上版本的新增功能:侦听器只执行一次

// 选项式 API
watch: {source: {handler(newValue, oldValue) {// 当 `source` 变化时,仅触发一次},// 开启单次监听once: true}
}
// 组合式 API
watch(source,(newValue, oldValue) => {// 当 `source` 变化时,仅触发一次},// 开启单次监听{ once: true }
)

改变侦听回调的触发时机

vue更新前回调(同步侦听)

若想在 Vue 进行任何更新之前触发侦听回调,则需添加 flush: 'sync' 选项,将其变成一个同步侦听器

// 选项式 APIwatch: {key: {handler() {},// 提前侦听回调flush: 'sync'}}
// 组合式 API
watch(source, callback, {flush: 'sync'
})

注意事项
同步侦听器不会进行批处理,每当检测到响应式数据发生变化时就会触发。可以使用它来监视简单的布尔值,但应避免在可能多次同步修改的数据源 (如数组) 上使用。

【默认】vue更新后,DOM 更新前回调

watch 的回调默认在父组件更新 (如有) 之后、所属组件的 DOM 更新之前执行,所以此时回调中访问的是所属组件更新之前的 DOM

DOM 更新后回调(后置侦听)

要想在回调中访问的是所属组件更新之后的 DOM,需添加 flush: 'post' 选项

// 选项式 APIwatch: {key: {handler() {},// 延后侦听回调flush: 'post'}}
// 组合式 API
watch(source, callback, {flush: 'post'
})

watchEffect()

仅组合式 API 可用

立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行

const count = ref(0)watchEffect(() => {// 在创建时,即执行第一次回调,并开始侦听count,在后续每次 count 发生变化时,都会触发回调console.log(count.value)
})
  • 自动追踪所有能访问到的响应式属性执行回调
  • 在创建时,就会执行一次(与 watch 添加了 immediate 选项的效果相同,其目的是收集要侦听的数据)

适用场景

  • 侦听的目标依赖于多个响应式数据
  • 侦听嵌套数据结构中的多个属性(可能会比深度侦听器性能更佳,因为它只跟踪回调中被使用到的属性,而不是递归地跟踪所有的属性)

注意事项

watchEffect 仅会在其同步执行期间,才追踪依赖。在使用异步回调时,只有在第一个 await 正常工作前访问到的属性才会被追踪。

同步侦听

vue更新前回调

import { watchEffect} from 'vue'watchEffect(callback, {flush: 'sync'
})

import { watchSyncEffect } from 'vue'watchSyncEffect(() => {/* 在响应式数据变化时同步执行 */
})

watchSyncEffect 是同步触发的 watchEffect 的别名

注意事项
同步侦听器不会进行批处理,每当检测到响应式数据发生变化时就会触发。可以使用它来监视简单的布尔值,但应避免在可能多次同步修改的数据源 (如数组) 上使用。

后置侦听

DOM 更新后回调

import { watchEffect} from 'vue'watchEffect(callback, {flush: 'post'
})

import { watchPostEffect } from 'vue'watchPostEffect (() => {/* 在 Vue 更新后执行 */
})

watchPostEffect 是后置刷新的 watchEffect 的别名

官方范例

watchEffect(async () => {const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${todoId.value}`)data.value = await response.json()
})

与下方 watch 的写法相比, watchEffect 更加方便和简洁

const todoId = ref(1)
const data = ref(null)watch(todoId,async () => {const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${todoId.value}`)data.value = await response.json()},{ immediate: true }
)

watch 和 watchEffect() 的区别

  • watch 只追踪明确侦听的数据源,在回调执行期间会避免追踪依赖,能更加精确地控制回调函数的触发时机。

  • watchEffect 会自动追踪所有能访问到的响应式属性,在回调执行期间会追踪依赖,导致其响应性依赖关系有时会不那么明确。

用 $watch() 创建侦听器

this.$watch('question', (newQuestion) => {
})

适用场景:

  • 在特定条件下设置一个侦听器
  • 只侦听响应用户交互的内容
  • 需要提前停止侦听器

手动停止侦听器

  • 用 watch 选项或者 $watch() 实例方法声明的侦听器,会在宿主组件卸载时自动停止。
  • 在 setup() 或 <script setup> 中用同步语句创建的侦听器,会自动绑定到宿主组件实例上,并且会在宿主组件卸载时自动停止。
  • 用异步回调创建的侦听器,不会绑定到当前组件上,必须手动停止它,以防内存泄漏。
<script setup>
import { watchEffect } from 'vue'// 异步回调创建的侦听器必须手动停止!
setTimeout(() => {watchEffect(() => {})
}, 100)
</script>

注意事项
需要异步创建侦听器的情况很少,请尽可能选择同步创建。如果需要等待一些异步数据,可以用条件式的侦听逻辑。

// 需要异步请求得到的数据
const data = ref(null)watchEffect(() => {if (data.value) {// 数据加载后执行某些操作...}
})
  • 调用 $watch() 或 watchEffect() 返回的函数,可手动停止侦听器
const unwatch = this.$watch('question', (newQuestion) => {
})// 当该侦听器不再需要时,停止该侦听器
unwatch()
const unwatch = watchEffect(() => {})// ...当该侦听器不再需要时
unwatch()

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

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

相关文章

京东微服务microApp使用总结

前言 基于现有业务门户进行微服务基础平台搭建 主应用框架&#xff1a;vue3vite 子应用框架&#xff1a;vue2webpack / vue3vite在这里插入代码片 本地调试即可&#xff1a;主应用子应用进行打通&#xff08;注意&#xff1a;两者都是vue3vite&#xff09; 问题总结 1.嵌入…

多数元素(C++)

给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 示例 1&#xff1a; 输入&#xff1a;nums [3,2,3] 输出&#xff1a;3 示例 …

pytorch框架下的逻辑回归代码解读

# -*- coding: utf-8 -*- """ # file name : lesson-05-Logsitic-Regression.py # author : tingsongyu # date : 2019-09-03 10:08:00 # brief : 逻辑回归模型训练 """ import torch import torch.nn as nn import matplotlib.…

压电式微机械超声换能器(PMUT)可替代传统超声换能器 下游应用范围广泛

压电式微机械超声换能器&#xff08;PMUT&#xff09;可替代传统超声换能器 下游应用范围广泛 压电式微机械超声换能器&#xff08;PMUT&#xff09;&#xff0c;是一种基于正逆压电效应与微机械&#xff08;MEMS&#xff09;技术制造而成的发射、接收超声波以实现检测的装置。…

个人开发 App 最简单方法:使用现代开发工具和平台

在移动应用市场的蓬勃发展下&#xff0c;个人开发者也有机会将自己的创意转化为实际的应用程序&#xff0c;并通过应用商店实现盈利。然而&#xff0c;对于许多初学者来说&#xff0c;如何开始个人开发一个应用可能会感到困惑。本文将介绍个人开发 App 的最简单方法&#xff0c…

Zynq7000系列中的IOP模块时钟使用

IOP模块的时钟&#xff08;用于内部控制器逻辑&#xff09;可以由时钟子系统生成&#xff0c;或者在某些情况下&#xff0c;由IOP的外部接口生成。在所有情况下&#xff0c;IOP的控制和状态寄存器都是由其AMBA接口时钟&#xff08;CPU_1x&#xff09;驱动的。有时&#xff0c;C…

ERESOLVE overriding peer dependency npm install错误

错误提示 npm ERR! Fix the upstream dependency conflict, or retry npm ERR! this command with --force, or --legacy-peer-deps npm ERR! to accept an incorrect (and potentially broken) dependency resolution. 根据提示解决办法之一 npm i --legacy-peer-deps –legac…

ESA SNAP更新失败

snap用起来真是一言难尽&#xff0c;老师原话&#xff1a;很拉&#xff0c;不更新进行处理又会报错&#xff08;本科的时候就已经体验过了&#xff09;&#xff0c;但是更新又会发现老是失败&#xff0c;just pop up a window: try again later、unable to connect to update c…

日本语自然语言处理中的分词库 - GiNZA

日本语自然语言处理中的分词库 - GiNZA 0. 引言1. 日本语分词库2. GiNZA3. 使用 GiNZA 0. 引言 RAG 场景下提供精确的一个手法就是使用 Hybrid Search&#xff0c;Hybrid Search的另外一个检索就是全文检索。 使用 Elastic Search 进行全文检索的方案应该比较成熟&#xff0c…

️️️Vue3+Element-Plus二次封装一个可定制化的table组件

前言 为什么需要二次封装 开发后台管理系统,会接触到很多表格和表单,一但表格表单多起来,仅仅只需要一小部分改变&#xff0c;都需要在中重写一大堆代码,许多重复逻辑,我们可以把重复逻辑抽离出来二次封装一个组件 使用,减少在开发中需要编写的代码。 为什么需要定制化 每个…

前端请求404,后端保无此方法

1、微信小程序前端路径404 2、后端报无此路径 3、查看路径下对应的方法 发现忘了在list方法前加GetMapping(“/list”)&#xff0c;加上即可

Eclipse 配置JDK版本,Eclipse Maven install 时使用的JDK版本

Eclipse配置JDK版本 Eclipse 配置JDK版本的地方&#xff1f; 在Eclipse中配置JDK版本的步骤如下&#xff1a; 打开Eclipse IDE。转到菜单栏并选择 “Window”&#xff08;窗口&#xff09;选项。在下拉菜单中选择 “Preferences”&#xff08;首选项&#xff09;&#xff0c;或…

【pyhon】while语句的题目

1.计算1至100的偶数之和 sum_even 0 # 初始化偶数之和为0 i 1 # 从1开始循环 while i < 100: # 当i小于或等于100时&#xff0c;继续循环 if i % 2 0: # 如果i是偶数 sum_even i # 将i加到偶数之和上 i 1 # i自增1 print(“1至100的偶数之和为:”, sum_even) 给出乘…

计算机网络练习-计算机网络体系结构与参考模型

计算机网络分层结构 ----------------------------------------------------------------------------------------------------------------------------- 1.在ISO/OSI参考模型中&#xff0c;实现两个相邻结点间流量控制功能的是( )。 A.物理层 B. 数据链路层 C.网络层 D.传…

计算机网络—TCP协议详解:协议构成、深度解析(2)

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;マリンブルーの庭園—ずっと真夜中でいいのに。 0:34━━━━━━️&#x1f49f;──────── 3:34 &#x1f504; ◀️…

M系Mac关闭SIP

文章目录 M系Mac关闭SIP一&#xff1a;查看SIP状态二&#xff1a;关闭SIP步骤 M系Mac关闭SIP 一&#xff1a;查看SIP状态 1、使用终端 打开终端 输入csrutil status&#xff0c;回车 你会看到以下信息中的一个&#xff0c;指示SIP状态 已打开 System Integrity Protection s…

Qt/C++音视频开发70-无感切换通道/无缝切换播放视频/多通道流畅切换/不同视频打开无缝切换

一、前言 之前就写过这个方案&#xff0c;当时做的是ffmpeg内核版本&#xff0c;由于ffmpeg内核解析都是代码实现&#xff0c;所以无缝切换非常完美&#xff0c;看不到丝毫的中间切换过程&#xff0c;看起来就像是在一个通道画面中。其实这种切换只能说是取巧办法&#xff0c;…

Spire.PDF for .NET【文档操作】演示:合并 PDF 文档

需要合并 PDF 的原因有很多。例如&#xff0c;合并 PDF 文件允许您打印单个文件&#xff0c;而不是为打印机排队多个文档&#xff0c;组合相关文件通过减少要搜索和组织的文件数量来简化管理和存储多个文档的过程。在本文中&#xff0c;您将学习如何使用Spire.PDF for .NET将多…

socket编程实现TCP通信

socket编程实现TCP通信 tcp_client.cc #include <iostream> #include <cstring> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <pthread.h> #include <unistd.h&…

CV 面试指南—深度学习知识点总结(4)

本期专栏文章: CV 面试指南—深度学习知识点总结(1)CV 面试指南—深度学习知识点总结(2)CV 面试指南—深度学习知识点总结(3)CV 面试指南—深度学习知识点总结(4)CV 面试指南—深度学习知识点总结(5)