Vue监听器(上)之组合式watch

1. 定义监听器

//要监视的属性被改变时触发
watch(要监视的属性, (更改后的心值, 更改前的旧值) => {具体操作},
);//监视对象为getter的时候
//表达式内任意响应式属性被改变时触发
watch(() => return表达式, (表达式的新值, 表达式的旧值) => {具体操作}
);//数组中任意下标数据被改变时触发
watch(value1, value2,....], ([value1改变后的值, value2改变后的值,...valuen改变后的值]) => {具体操作}
);//对象内任意属性被改变时
watch(obj对象, (对象的新值, 对象的旧值) => {具体操作,但需要注意这时对象的新值和对象的旧值是相等的,显示对象新值
});//当对象下某个属性发生改变时,监视对象下某一属性
watch(() => 对象的属性,(对象属性的新值, 对象属性的旧值) => {具体操作}
);//使用watchEffect监视
watchEffect(()=>{函数式,在函数式中定义的属性被改变时触发
})

2. 监听器的配置项

开启深层监听:deep: true
强制监视器立即执行:immediate: true
一次性监听:once: true
监听器回调中访问被vue更新之后的所有组件dom:flush: ‘post’
同步触发监听器,会在Vue进行任何更新之前触发:flush: ‘sync’

3. 监听器实例

<template><div>{{ count }}</div><br /><button @click="addcount">count++</button><br /><div>{{ obj.nums }}</div><br /><button @click="addobjnums">obj.nums++</button><br><button @click="addobjnums2">obj.nums2++</button>
</template>
<script setup>
import { ref, reactive, watch } from "vue";
name: "App";
let count = ref(0);
let x = ref(5);
let obj = reactive({nums: 1,nums2: 2,
});//使用immediate: true 配置项实现在页面初始化时就执行此监视属性
watch(count, (newValue, oldValue) => {console.log("---------这个是页面初始化出来的/如果你第二次看见我则是count值发生改变时看到的------");console.log("count原始值:", oldValue);console.log("count更改后的值:", newValue);},{ immediate: true }
);//单纯监视count是否有变化,
//监视函数会获得俩个参数,第一个为更新后的值,第二个为更新前的值
watch(count, (newValue, oldValue) => {console.log("----------------------------监视单个ref-----------------------");console.log("count原始值:", oldValue);console.log("count更改后的值:", newValue);
});//监视对象为getter的时候
watch(() => count.value + x.value,(newValue, oldValue) => {console.log("----------------------------监视getter函数-----------------------");console.log("getter原始值:", oldValue);console.log("count更改后getter函数的值:", newValue);}
);//监视对象来源于一个数组,没有找到获取原来值的写法
watch([count, () => x.value + 1], ([newCount, newX]) => {console.log("-----------------------监视多个来源组成的数组-------------------");console.log("count更改后的值:", newCount);console.log("x+1后的值:", newX);
});//当监视对象为整个对象时
//这时newValue和oldValue是相等的,因为是同一个对象
watch(obj, (newValue, oldValue) => {console.log("----------------------------监视整个对象时-----------------------");console.log("obj原始值:", oldValue);console.log("obj更改后的值:", newValue);
});//当监视对象为对象属性时,需监视其对象属性的getter函数
//这个触发条件仅仅是obj.nums被修改的时候出发
watch(() => obj.nums,(newValue, oldValue) => {console.log("----------------------------监视对象下单个属性-----------------------");console.log("obj.nums原始值:", oldValue);console.log("obj.nums更改后的值:", newValue);}
);//看起来是监视了obj对象下的nums属性,
//其实是通过deep:true选项开启了深层监听器
//其返回的原值和新值为obj对象的值,而不是obj.nums单个
//注意这个非常耗费资源,是遍历实现的
watch(() => obj.nums,(newValue, oldValue) => {console.log("------------开启深层监听器检测obj下的所有属性只要其中一个发生改变就会输出整个obj对象------------");console.log("obj原始值:", oldValue);console.log("obj更改后的值:", newValue);},{ deep: true }
);//使用once: true 配置项实现此监视只执行一次
watch(count, (newValue, oldValue) => {console.log("---------这个只会看到一次------");console.log("count原始值:", oldValue);console.log("count更改后的值:", newValue);},{ once: true }
);//使用watchEffect可以不写监视属性
//在匿名函数中存在的属性被修改时会触发
watchEffect(()=>{count.value++
})function addcount() {count.value++;
}
function addobjnums() {obj.nums++;
}
function addobjnums2() {obj.nums2++;
}
</script><style scoped>
</style>

在这里插入图片描述

4. 监听器其他
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 }
)

使用watchEffect()函数后

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

watch 和 watchEffect 都能响应式地执行有副作用的回调。它们之间的主要区别是追踪响应式依赖的方式:
watch 只追踪明确侦听的数据源。它不会追踪任何在回调中访问到的东西。另外,仅在数据源确实改变时才会触发回调。watch 会避免在发生副作用时追踪依赖,因此,我们能更加精确地控制回调函数的触发时机。
watchEffect,则会在副作用发生期间追踪依赖。它会在同步执行过程中,自动追踪所有能访问到的响应式属性。这更方便,而且代码往往更简洁,但有时其响应性依赖关系会不那么明确。

Post Watchers​
如果想在侦听器回调中能访问被 Vue 更新之后的所属组件的 DOM,你需要指明 flush: ‘post’ 选项:

watch(source, callback, {flush: 'post'
})watchEffect(callback, {flush: 'post'
})

后置刷新的 watchEffect() 有个更方便的别名 watchPostEffect():

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

同步侦听器
你还可以创建一个同步触发的侦听器,它会在 Vue 进行任何更新之前触发:

watch(source, callback, {flush: 'sync'
})watchEffect(callback, {flush: 'sync'
})

同步触发的 watchEffect() 有个更方便的别名 watchSyncEffect():.

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

停止侦听器
在 setup() 或

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

<script setup>
import { watchEffect } from 'vue'// 它会自动停止
watchEffect(() => {})// ...这个则不会!
setTimeout(() => {watchEffect(() => {})
}, 100)
</script>

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

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

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

// 需要异步请求得到的数据
const data = ref(null)watchEffect(() => {if (data.value) {// 数据加载后执行某些操作...}
})

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

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

相关文章

【MySQL】多表操作、事务、索引

MySQL MYSQL 多表设计 一对多插入测试数据外键约束(物理外键)使用逻辑外键 MYSQL 多表设计 一对一表结构 MYSQL 多表设计 多对多 MYSQL 多表设计 一对多 建表语句 员工表 CREATE TABLE tb_emp (id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT COMMENT ID,username VARCHAR(20) N…

图片大了怎么缩小上传?30秒解决图片大小问题

在上传图片到网站、社交媒体、电子邮件或其他在线平台时&#xff0c;压缩图片可以减小文件大小&#xff0c;加快上传速度&#xff0c;并节省带宽和存储空间&#xff0c;许多网站和应用程序都有对上传图片大小的限制&#xff0c;因此利用在线图片压缩工具&#xff08;https://ww…

WordPres Bricks Builder 前台RCE漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

Jetpack Compose 架构层

点击查看&#xff1a;Jetpack Compose 架构层 官网 本页面简要介绍了组成 Jetpack Compose 的架构层&#xff0c;以及这种设计所依据的核心原则。 Jetpack Compose 不是一个单体式项目&#xff1b;它由一些模块构建而成&#xff0c;这些模块组合在一起&#xff0c;构成了一个完…

VSCODE include错误 找不到 stdio.h

解决办法&#xff1a; Ctrl Shift P 打开命令面板&#xff0c; 键入 “Select Intellisense Configuration”&#xff08;下图是因为我在写文章之前已经用过这个命令&#xff0c;所以这个历史记录出现在了第一行&#xff09; 再选择“Use gcc.exe ”&#xff08;后面的Foun…

C语言-数组指针与指针数组

一、简介 对于使用C语言开发的人来说&#xff0c;指针&#xff0c;大家都是非常熟悉的。数组&#xff0c;大家也同样熟悉。但是这两个组合到一起的话&#xff0c;很多人就开始蒙圈了。这篇文章&#xff0c;就详细的介绍一下这两个概念。 指针数组和数组指针&#xff0c;听起来非…

PyTorch概述(二)---MNIST

NIST Special Database3 具体指的是一个更大的特殊数据库3&#xff1b;该数据库的内容为手写数字黑白图片&#xff1b;该数据库由美国人口普查局的雇员手写 NIST Special Database1 特殊数据库1&#xff1b;该数据库的内容为手写数字黑白图片&#xff1b;该数据库的图片由高…

互联网广告投放与IP地理位置定位

随着互联网的发展和普及&#xff0c;互联网广告投放成为各行业推广营销的重要方式之一。而结合IP地理位置定位技术&#xff0c;可以实现精准定向&#xff0c;提高广告投放的效果和精准度。IP数据云将探讨互联网广告投放与IP地理位置定位的关系&#xff0c;分析其优势和应用场景…

动态规划算法学习(基础)

做题步骤&#xff1a; 确定dp数组的含义(一维或者二维) 获取递推公式 dp数组如何初始化 确定遍历顺序 打印dp数组&#xff08;检查&#xff09; 题目&#xff1a; 1. 斐波那契数 509 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 …

留子厨房开发日志

以下记录了使用go语言框架Beego&#xff0c;Mysql数据库&#xff0c;Redis数据库实现一个点菜/菜谱应用API的全过程。 技术方案 github地址 数据库设计 新建数据库&#xff1a; CREATE DATABASE menu;新建数据表&#xff1a; CREATE TABLE menu ( id int(10) unsigned NOT …

2024 CKS 题库 | 11、AppArmor

不等更新题库 CKS 题库 11、AppArmor Context: APPArmor 已在 cluster 的工作节点node02上被启用。一个 APPArmor 配置文件已存在&#xff0c;但尚未被实施。 Task: 在 cluster 的工作节点node02上&#xff0c;实施位于 /etc/apparmor.d/nginx_apparmor 的现有APPArmor 配置…

Python 实现 ADTM 指标计算:股票技术分析的利器系列(9)

Python 实现 ADTM 指标计算&#xff1a;股票技术分析的利器系列&#xff08;9&#xff09; 介绍算法解释 核心代码rolling函数介绍计算 DTMnp.where 使用介绍np.maximum 计算 DBM计算 STM计算 SBM计算 ADTM 完整代码 介绍 ADTM&#xff08;动态买卖气指标&#xff09;是一种用…

C++奇怪的 ::template

答疑解惑 怎么会有::template的写法 起初 在阅读stl的源码的时候&#xff0c;发现了一条诡异的代码 // ALIAS TEMPLATE _Rebind_alloc_t template<class _Alloc,class _Value_type> using _Rebind_alloc_t typename allocator_traits<_Alloc>::template rebind…

【misc | CTF】攻防世界 simple_transfer

天命&#xff1a;这题其实不简单啊 拿到流量包&#xff0c;丢进去wireshare&#xff0c;题目都说了flag在里面 ctrl f 直接搜索字符串 右键&#xff0c;追踪流 -> TCP流 查找 .pdf 文件&#xff0c;其实这里思路是比较奇怪的&#xff0c;毕竟是的确比较多内容&#xff0c…

基于PostGIS的慢查询引起的空间索引提升实践

目录 前言 一、问题定位 1、前端接口定位 2、后台应用定位 3、找到问题所在 二、空间索引优化 1、数据库查询 2、创建空间索引 3、geography索引 4、再看前端响应 总结 前言 这是一个真实的案例&#xff0c;也是一个新入门的工程师很容易忽略的点。往往在设计数据库的…

NestJS入门4:MySQL typeorm 增删改查

前文参考&#xff1a; NestJS入门1 NestJS入门2&#xff1a;创建模块 NestJS入门3&#xff1a;不同请求方式前后端写法 1. 安装数据库相关模块 npm install nestjs/typeorm typeorm mysql -S 2. MySql中创建数据库 ​ 3. 添加连接数据库代码 app.module.ts ​ import { M…

给自己留个备忘,blender是右手坐标系

所谓右手坐标系&#xff0c;就是三个轴的方向和右手三根手指的方向一致&#xff08;当然&#xff0c;有要求的&#xff0c;这个要求是大拇指指向x轴方向&#xff0c;食指指向y轴方向,中指指向z轴方向&#xff09;。 不过blender默认是z轴朝上的&#xff0c;如下图。 右手坐标系…

element导航菜单el-menu添加搜索功能

element导航菜单-侧栏&#xff0c;自带的功能没有搜索或者模糊查询。 找了找资料 找到一个比较可行的&#xff0c;记录一下&#xff1a; //index.vue的代码 <div style"overflow:auto"><el-menu :default-active"$route.path":default-openeds&…

<网络安全>《49 网络攻防专业课<第十三课 - 华为防火墙的使用(2)>

6 防火墙的防范技术 6.1 ARP攻击防范 攻击介绍 攻击者通过发送大量伪造的ARP请求、应答报文攻击网络设备&#xff0c;主要有ARP缓冲区溢出攻击和ARP拒绝服务攻击两种。 ARP Flood攻击&#xff08;ARP扫描攻击&#xff09;&#xff1a;攻击者利用工具扫描本网段或者跨网段主机时…

构造器详解

定义: 是一种特殊类型的方法&#xff0c;用于创建对象时初始化对象的状态。 使用new关键字创建对象 构造器特点: 1.和类名相同 2.没有返回值 public class Person {String name;public Person() {this.name"John";}}public class Test {public static void main…