详细介绍 Vue3 的 watch 和 watchEffect

news2024/9/21 18:38:34

在 Vue 3 中,watch 和 watchEffect 都是用于响应式地监听数据变化的工具,但它们有不同的使用场景和工作机制。

1. watch

1、概念

watch 是 Vue 3 提供的一个用于观察响应式数据变化并在数据发生变化时执行特定操作的工具。它通常用于执行副作用,例如异步操作、手动更新 DOM、数据同步等。

2、用法

<template>
  <div>
    <p>count:{{ count }}</p>
    <p>num:{{ state.num }}</p>
  </div>
</template>

<script setup>
import { ref, watch ,reactive } from 'vue'

const count = ref(0);
// 写法一
watch(count, (newValue, oldValue) => {
  console.log(`count changed from ${oldValue} to ${newValue}`)
})
// 写法二
watch(() => count.value, (newValue, oldValue) => {
  console.log(`count changed from ${oldValue} to ${newValue}`)
})

const state = reactive({ num: 0 })
watch(
  () => state.num,
  (newValue, oldValue) => {
    console.log(`num changed from ${oldValue} to ${newValue}`);
  },
);

window.count = count;
window.state = state;
</script>

3、特性

1)明确依赖:watch 需要明确指定监听的响应式数据,可以是 ref、reactive 对象的属性,甚至是一个返回响应式数据的函数。

2)旧值和新值:watch 回调函数的参数包括新值和旧值,在数据变化时进行后续操作很方便。

3)异步操作:watch 常用于监听数据变化并触发异步操作,如 API 请求、延迟处理等。

4)深度监听:通过设置 deep: true,watch 可以对嵌套对象或数组进行深度监听。

⚠️:深度监听需要递归遍历对象或数组的每一个属性。这种情况下,可能导致性能问题,尤其是在大型应用中。

<template>
  <div>
    <p>state.nested.count:{{ state.nested.count }}</p>
  </div>
</template>
import { reactive, watch } from 'vue'

const state = reactive({
  nested: {
    count: 0
  }
})
watch(
  () => state.nested,
  (newValue, oldValue) => {
    console.log('nested count changed:', newValue.count)
  },
  { deep: true }
)
window.state = state;

若是不添加 deep:true,则只是单纯的修改数据,而不执行 watch。

注意⚠️

state.nested 是一个响应式对象,当使用 watch 监听时,Vue 实际上是监测对象引用的变化。在 JS 中,newValue 和 oldValue 都是对同一个对象的引用。由于 reactive 对象是通过代理实现的,这意味着无论 newValue 还是 oldValue 都指向同一个代理对象,因此二者是相同的。

2. watchEffect

1、概念

watchEffect 是 Vue 3 引入的一种更为自动化的监听机制。它在函数内部自动收集依赖,任何响应式数据的变化都会触发这个函数重新执行。watchEffect 更加简洁,适用于无需明确指定监听数据源的场景。

2、用法

watchEffect 接收一个函数,这个函数会立即执行一次,并且在函数中访问到的所有响应式数据发生变化时再次执行。

<template>
  <div>
    <p>count:{{ count }}</p>
  </div>
</template>

<script setup>
import { ref, watchEffect } from 'vue'

const count = ref(0);
watchEffect(() => {
  console.log(`count is now: ${count.value}`)
})
window.count = count;
</script>


watchEffect 监听的数据多次调用时,会存在缓存。

import { reactive, ref, watchEffect } from "vue";
const state = reactive({ a: 1, b: 2 });
const countRef = ref(0);

watchEffect(() => {
  console.log('state.a:', state.a, 'countRef.value:', countRef.value);
});

state.a++;
state.a++;
state.a++;
countRef.value++;
countRef.value++;
countRef.value++;

3、特性

1)自动依赖收集:watchEffect 不需要显式声明依赖项,它会自动收集函数内部使用的所有响应式数据并进行监听。

2)立即执行:watchEffect 在注册时立即执行一次,而不需要等待数据发生变化。

3)无需旧值对比:与 watch 不同,watchEffect 不会提供新旧值的对比,因为它主要用于自动处理副作用,而不是跟踪数据变化的前后差异。

4)停止侦听:watchEffect 返回一个停止侦听的函数,调用可以停止 effect 的依赖追踪。

const stop = watchEffect(() => {
  console.log(`count is now: ${count.value}`);
});

stop(); // 调用后将停止 watchEffect 的监听

3. 联系与区别

1、联系

两者都是基于 Vue 3 响应式系统的监听工具,都可以用于在数据变化时执行副作用。

2、区别

1)依赖声明方式

- watch 需要手动声明依赖的数据,可以明确指定监听的数据,适合复杂场景。

- watchEffect 自动收集依赖,不需要手动指定,适合简单的、与 UI 强相关的场景。

2)执行时机

- watch 在数据发生变化时才执行,当在 options 中配置 immediate:true,函数在最开始立即执行。

- watchEffect 在注册时立即执行一次,然后在依赖变化时再次执行。

import { ref, watch } from 'vue'

const count = ref(0)
watch(
  () => count.value,
  (newValue, oldValue) => {
    console.log(`count changed from ${oldValue} to ${newValue}`)
  },
  {
    immediate: true
  }
)
count.value++;

3)处理复杂性

- watch 提供了更复杂的功能,如访问旧值、新值、深度监听、监听多个数据源等,适合需要精细控制的场景。

- watchEffect 简洁高效,适合简单的逻辑和不需要复杂控制的场景。

4. 实际开发中的使用建议

1、在简单的数据响应和副作用处理中,优先考虑使用 watchEffect,因为它更加简洁和自动化。
  
2、如果需要更精细的控制,比如对比新旧数据、深度监听对象、处理异步操作等,则使用 watch。

无论是 watchEffect 还是 watch,当依赖项发生变化时,回调函数的运行都是异步的,存放在微队列中。

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

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

相关文章

LeetCode 热题 HOT 100 (023/100)【宇宙最简单版】

【技巧】No. 0647 回文子串【中等】&#x1f449;力扣对应题目指路 希望对你有帮助呀&#xff01;&#xff01;&#x1f49c;&#x1f49c; 如有更好理解的思路&#xff0c;欢迎大家留言补充 ~ 一起加油叭 &#x1f4a6; 欢迎关注、订阅专栏 【力扣详解】谢谢你的支持&#xff…

基于spring boot的疫情信息管理系统

TOC springboot255基于spring boot的疫情信息管理系统 绪论 1.1研究背景与意义 信息化管理模式是将行业中的工作流程由人工服务&#xff0c;逐渐转换为使用计算机技术的信息化管理服务。这种管理模式发展迅速&#xff0c;使用起来非常简单容易&#xff0c;用户甚至不用掌握…

CSC5812C 同步降压5V2.5A DC/DC车载充电方案

CSC5812C 是一款同步降压型的 DC/DC 变换器 IC &#xff0c;CSC5812C输入电压为 8~30V &#xff0c;可取得 2.5A恒定输出电流&#xff0c;开关频率 120kHz 左右&#xff0c;具有良好的瞬态响应和环路稳定性。CSC5812C 外围元器件极少&#xff0c;具有线补、过流保护和热保护功能…

Android全面解析之context机制(二): 从源码角度分析context创建流程(上)

前言 这篇文章从源码角度分析context创建流程。 在上一篇Android全面解析之Context机制(一) :初识context一文中讲解了context的相关实现类。经过前面的讨论&#xff0c;读者对于context在心中有了一定的理解。但始终觉得少点什么&#xff1a;activity是什么时候被创建的&…

IDEA终端无法打开,解决方法

检查终端路径&#xff1a; 确保你的系统终端路径被正确设置在你的开发环境或IDE的配置中。例如&#xff0c;在Windows上&#xff0c;这通常是cmd.exe、PowerShell或Git Bash的路径&#xff1b;在macOS或Linux上&#xff0c;这通常是/bin/bash、/bin/zsh等。 2.权限问题&#…

CTFSHOW 萌新 web13 解题思路和方法(利用?>提前结束语句)

点击题目链接&#xff0c;分析代码。发现相比上一关卡&#xff0c;增加过滤了分号。 此时&#xff0c;如果按照之前的方式构造url语句&#xff0c;发现由于分号的存在导致返回cmd error信息。 因为php中最后一行代码的结尾如果不接分号&#xff0c;也会被正常执行。 此时我们可…

Python 设计模式之享元模式

文章目录 从一个 MP3 案例谈起flyweight 模式解决flyweight pattern 的组件拆解定义与逐步实现完整代码 未讨论问题 享元模式&#xff08; flyweight pattern&#xff09;属于结构型设计模式&#xff0c;主要用于解决系统中大量创建同一个类的实例时导致的内存激增的问题&…

国产崛起,Solon:我们的性能是 Spring 的 300%

Solon 应用开发框架&#xff08;java framework&#xff09;。是从零开始构建&#xff0c;有自主的标准规范与开放生态。纯血国产。 追求&#xff1a; 更快、更小、更简单提倡&#xff1a; 克制、简洁、高效、开放、生态 相对于 Spring 应用开发框架。并发高 300%&#xff1b…

el-cascader多选的父子关联和父子不关联功能

公用html&#xff1a; <el-cascader v-model"data" :options"optionsData" :props"props" clearable> </el-cascader> 公用js变量&#xff1a; data () {return {// 绑定的数组data: [],// 绑定的选项数据optionsData: []} }, 公…

python自动化笔记:操作mysql数据库

操作mysql数据库常见方法 1、第三方库&#xff1a;pymysql1.1、安装pymysql1.2、连接数据库1.3、连接指定数据库1.4 创建数据库、创建表1.5、表中插入数据1.6、批量插入数据1.7、获取查询结果数据1.8、防sql注入&#xff0c;sql语句中一般用占位符传值 2、标准库 &#xff1a;m…

OpenCV图像处理——按最小外接矩形剪切图像

引言 在图像处理过程中&#xff0c;提取感兴趣区域&#xff08;ROI&#xff09;并在其上进行处理后&#xff0c;往往需要将处理后的结果映射回原图像。这一步通常涉及以下几个步骤&#xff1a; 找到最小外接矩形&#xff1a;使用 cv::boundingRect 或 cv::minAreaRect 提取感兴…

Jenkins默认工作目录修改及迁移(Windows)

问题描述 如果Jenkins安装时安在C盘&#xff0c;那么默认的空间就是C:\ProgramData\Jenkins.jenkins&#xff0c;git下拉的项目会在该目录的workspace下&#xff0c;造成C盘空间增大。网上方法倒是有&#xff0c;五花八门&#xff0c;我这里是Windows&#xff0c;是有更简单的…

前端工程化14-git merge 以及 git rebase。

rebase会把当前分支的 commit 放到公共分支的最后面,所以叫变基。就好像从公共分支又重新拉出来这个分支一样。 举例&#xff1a; 如果从 master 拉个feature分支出来,然后提交了几个 commit,这个时候刚好有人把他开发的东西合并到 master 了,这个时候 master 就比你拉分支的…

VoxelNet: End-to-End Learning for Point Cloud Based 3D Object Detection

VoxelNet: End-to-End Learning for Point Cloud Based 3D Object Detection Abstract 摘要部分&#xff0c;作者首先指出了3D点云中目标检测的重要性&#xff0c;在自动驾驶导航、家政机器人以及增强现实和虚拟现实等多个领域有重要的作用。然后&#xff0c;提到了现有方法的…

C语言实现多种快速排序

目录 1.概念 2.快速排序hoare版本 2.1基本思想 2.2解释相遇处的值为何一定小于key 2.3hoare版本快速排序的实现 3.快速排序挖坑法 3.1基本思想 3.2挖坑法快速排序的实现 4. 快速排序前后指针版本 4.1基本思想 4.2快速排序前后指针版本实现 5.快速排序非递归版本 …

Linux下如何使用Curl进行网络请求

在Linux系统上&#xff0c;Curl是一个非常强大的网络请求工具&#xff0c;可以用于发送各种类型的HTTP请求&#xff0c;并获取响应结果。它支持常见的HTTP方法&#xff0c;如GET、POST、PUT、DELETE等&#xff0c;还支持HTTPS、FTP等不同协议。Curl提供了丰富的参数选项&#x…

多智能体新进展||斯坦福大学提出新模型‘Hypothetical Minds‘,让AI更懂人类思维

AI论文解读轻松掌握AI前沿技术进展&#xff0c;实时追踪AI动态&#xff0c;互动交流&#xff0c;共同成长进步 标题&#xff1a;Hypothetical Minds: Scaffolding Theory of Mind for Multi-Agent Tasks with Large Language Models 作者&#xff1a;Logan Cross, Violet Xia…

[数据集][图像分类]超声波肾脏结石分类数据集9416张2类别

数据集类型&#xff1a;图像分类用&#xff0c;不可用于目标检测无标注文件 数据集格式&#xff1a;仅仅包含jpg图片&#xff0c;每个类别文件夹下面存放着对应图片 图片数量(jpg文件个数)&#xff1a;9416 分类类别数&#xff1a;2 类别名称:["normal","stone&…

链表(哈希表,有序表)环形链表确定节点的方式

UnOrderedMap UnSortedMap --> C 哈希表&#xff08;无序组织&#xff09; 哈希表如果只有key 没有 value 是HashSet 哈希表如果有key 有 value 是HashMap 哈希表在使用的过程中所有的增删改查都是常数时间&#xff08;比较大&#xff09; 如果存放的是基础类型&#xf…