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.mfbz.cn/a/409449.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

四六级成绩爬取代码原创

在六级成绩刚发布时&#xff0c;只需要通过学生姓名和身份证号便可以查询到成绩 据此&#xff0c;我们可以利用selenium框架对学生的成绩进行爬取 首先我们要建立一个excel表格&#xff0c;里面放三列&#xff08;多几列也无所谓&#xff09;&#xff0c;第一列列名取为学生姓…

在openEuler中通过KVM可视化安装华为FusionCompute的VRM节点

一、说明 本文是华为FusionCompute云平台配置的延续&#xff0c;是在CNA&#xff08;ComputingNode Agent&#xff0c;计算节点代理&#xff09;主机安装配置完成后&#xff0c;详细安装VRM&#xff08;Virtual Resource Manager&#xff0c;虚拟资源管理器&#xff09;节点的…

基于Clion+stm32cubemx+rt-thread os进行环境搭建

前言 RT-Thread文档中心Clion开发STM32的环境搭建,请参考之前的文章本次使用的芯片为STM32F407VET6,其他芯片相似.项目创建 使用STM32CubeMx快速生成项目工程,此步骤的话可以参考官方文档 基础配置如下

AtCoder ABC341 A-D题解

比赛链接:ABC341 Problem A: 先签个到。 #include <bits/stdc.h> using namespace std; int main() {int n;cin>>n;for(int i0;i<n;i)cout<<"10"<<endl;cout<<"1"<<endl;return 0; } Problem B: 继续签。 #i…

在 where子句中使用子查询(二)

目录 ANY ANY &#xff1a;功能上与 IN 是没有任何区别的 >ANY &#xff1a;比子查询返回的最小值要大 ALL >AL &#xff1a;比子查询返回的最大值要大 EXISTS() 判断 NOT EXISTS Oracle从入门到总裁:https://blog.csdn.net/weixin_67859959/article/details/135209…

【Go的函数】

函数 函数的引入函数细节祥讲包的引入包的细节详讲init函数匿名函数闭包defer关键字系统函数字符串相关函数日期和时间相关函数内置函数 函数的引入 【1】为什么要使用函数&#xff1a; 提高代码的复用&#xff0c;减少代码的冗余&#xff0c;代码的维护性也提高了 【2】函数…

论文解析——Review of chiplet-based design: system architecture and interconnection

作者 Liu Yafei1, Li Xiangyu2, YIN ShouYi1, Review of chiplet-based design: system architecture and interconnection, SCIENCE CHINA Information Sciences, 2024, ISSN 1674-733X, https://doi.org/10.1007/s11432-023-3926-8. 1School of Integrated Circuit, Tsingh…

来看大厂如何设计运营后台系统的?

0 背景 重运营的应用。对于App里的顶导航、我的页面、弹窗等&#xff0c;需要根据模式、版本、平台、语言、渠道等不同的维度进行运营管理。随着业务快速发展&#xff0c;版本快速迭代&#xff0c;如何&#xff1a; 保持运营资源能够被高效、稳定和灵活地配置高效稳定的为新的…

软件游戏显示d3dx9_42.dll丢失的5种解决方法,快速解决dll问题

当计算机系统中d3dx9_42.dll文件丢失时&#xff0c;可能会引发一系列运行问题和功能异常&#xff0c;具体表现形式多样且影响范围较广。首先&#xff0c;对于依赖于DirectX 9.0c版本的各类应用程序&#xff0c;尤其是部分经典的老款游戏&#xff0c;由于d3dx9_42.dll是其中不可…

深度解析:Integer.parseInt() 源码解读

深度解析&#xff1a;Integer.parseInt() 源码解读 关键要点 解析字符&#xff1a;用于将字符转换为对应的数字值 Character.digit(s.charAt(i),radix) 确定limit&#xff1a;根据正负号分别设定 int limit -Integer.MAX_VALUE;【正】 limit Integer.MIN_VALUE;【负】 负数…

【卷积神经网络中用1*1 卷积有什么作用或者好处呢?】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;深度学习 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 1*1 卷积有什么作用或者好处呢 作用降维和增加非线性特征组合和交互网络的宽度和深度调整全连接替代增强…

matlab滤波器设计

1、内容简介 略 51-可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 略 matlab滤波器设计-butter、ellip、cheby1、cheby2_哔哩哔哩_bilibili 4、参考论文 略

C语言中的宏定义与内联函数的使用

大家好&#xff0c;今天给大家介绍C语言中的宏定义与内联函数的使用&#xff0c;文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 一、宏定义&#xff08;Macro Definition&#xff09; 宏定…

英伟达狂飙,上演大象坐火箭

英伟达市值破 2W 亿 这两天全球资本市场最大的事情就是英伟达&#xff08;NVDA&#xff09;公布了财报。 本来市场&#xff08;分析师&#xff09;的预期就高&#xff0c;结果财报公布比预期还要高出不少。 NVDA 直接上演「大象坐火箭」&#xff0c;在财报公布后的第一个交易日…

【数据结构与算法】(19)高级数据结构与算法设计之 图 拓扑排序 最短路径 最小生成树 不相交集合(并查集合)代码示例

目录 6) 拓扑排序KahnDFS 7) 最短路径DijkstraBellman-FordFloyd-Warshall 8) 最小生成树PrimKruskal 9) 不相交集合&#xff08;并查集合&#xff09;基础路径压缩Union By Size 图-相关题目 6) 拓扑排序 #mermaid-svg-MQhLsXiMwnlUL3q4 {font-family:"trebuchet ms"…

语音转字幕:Whisper模型的功能和使用

&#x1f341; 作者&#xff1a;知识浅谈&#xff0c;CSDN签约讲师&#xff0c;CSDN博客专家&#xff0c;华为云云享专家&#xff0c;阿里云专家博主 &#x1f4cc; 擅长领域&#xff1a;全栈工程师、爬虫、ACM算法 &#x1f492; 公众号&#xff1a;知识浅谈 &#x1f91e;语音…

【k8s资源调度-HPA(自动扩缩容)】

1、HPA可以做什么&#xff1f; 通过观察pod的cpu、内存使用率或自定义metrics指标进行自动的扩容或缩容pod的数量。通常用于Deployment&#xff0c;不适用于无法扩/缩容的对象&#xff0c;如DaemonSet。控制管理器每隔30s(可以通过-horizontal-pod-autoscaler–sync-period修改…

信息系统项目管理师论文分享(质量管理)

水一篇文章。我发现身边考高项的朋友很多都是论文没过&#xff0c;我想着那就把我的论文分享出来&#xff0c;希望能有帮助。 质量管理 摘要 2020年5月&#xff0c;我作为项目经理参加了“某市某医联体的互联网诊疗&#xff08;互联网医院和远程医疗&#xff09;平台”的建设…

多表联合分页查询(二)---- springboot整合MybatisPlus分页代码

目录 一、分页配置代码解读&#xff08;使用MP自带分页&#xff09;二、Controller层代码解读三、service层代码解读四、Mapper层代码解读五、结果展示 一、分页配置代码解读&#xff08;使用MP自带分页&#xff09; package com.minster.yanapi.Config;import com.baomidou.m…

Python 读取txt中的汉字报错

Python读取txt中的汉字报错&#xff1a;UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0xa7 in position 4: illegal multibyte sequence 举例&#xff1a; fileE:/0_MyWork/python_programm/children_name/strich7.txtwith open(file, "r") as file_7str…
最新文章