Vue3的watchEffect的妙用,与watch的区别

news2024/11/25 20:50:49

前言

在Vue3中,引入了Composition API,其中的watchEffect()函数是一个非常强大和灵活的工具,用于处理响应式数据的变化,使得项目更加弹性和灵活。它与watch有所不同,本文将介绍watchEffect()的定义、特点、与watch的区别以及使用时的注意事项。

一、定义

watchEffect()函数用于创建一个自动追踪依赖的响应式副作用。它会在初始化时会立即执行一次,并自动追踪在回调函数中使用的所有响应式数据,在这些数据发生变化时重新运行回调函数。

例如,在每当 todoId 的引用发生变化时使用侦听器来加载一个远程资源,如果用watch,是这么写:

<template>
  <div>Test</div>
</template>

<script setup>
  import { ref, watch } from 'vue'
  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()
      console.log(data.value)
    },
    { immediate: true }
  )
</script>

打印:

但是用了watchEffect()就可以简化为:

<template>
  <div>Test</div>
</template>

<script setup>
  import { ref, watchEffect } from 'vue'
  const todoId = ref(1)
  const data = ref(null)

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

 打印:

两者都立即打印了data。但下面的例子中,回调会立即执行,不需要指定 immediate: true。在执行期间,它会自动追踪 todoId.value 作为依赖(和计算属性类似)。每当 todoId.value 变化时,回调会再次执行。有了 watchEffect(),我们不再需要明确传递 todoId 作为源值。

从这个角度来看,watchEffect()的作用类似于Vue2中的computed,即依赖项发生变化,自己也跟着改变。但与computed不同,watchEffect()没有返回值,而是直接执行回调函数。

二、特点

watchEffect()自动追踪其回调函数中使用的所有响应式数据,并在这些数据发生变化时重新运行回调函数。这使得我们无需手动指定要监听的具体属性,减少了代码的冗余。

    对于这种只有一个依赖项的例子来说,watchEffect() 的好处相对较小。但是对于有多个依赖项的侦听器来说,使用 watchEffect() 可以消除手动维护依赖列表的负担。

    此外,如果你需要侦听一个嵌套数据结构中的几个属性,watchEffect() 可能会比深度侦听器更有效,因为它将只跟踪回调中被使用到的属性,而不是递归地跟踪所有的属性。 

多个依赖项例子:

<template>
  <div>Test</div>
</template>

<script setup>
  import { reactive } from 'vue'
  const state = reactive({
    count: 0,
    name: 'John',
    age: 25
  })

  // 使用watchEffect()监听count和name的变化
  watchEffect(() => {
    console.log('count or name changed:', state.count, state.name)
  })

  // 模拟count和name变化
  setTimeout(() => {
    state.count = 1 // 输出'count or name changed: 1 John'
    state.name = 'Alice' // 输出'count or name changed: 1 Alice'
  }, 1000)
</script>

打印:

深度依赖例子:

<template>
  <div>Test</div>
</template>

<script setup>
  import { reactive, watchEffect } from 'vue'
  const state = reactive({
    person: {
      name: 'John',
      age: 25
    },
    todos: [
      { text: 'Task 1', completed: false },
      { text: 'Task 2', completed: true },
      { text: 'Task 3', completed: false }
    ]
  })

  // 使用watchEffect()监听person对象中name和age的变化
  watchEffect(() => {
    console.log('person changed:', state.person.name, state.person.age)
  })

  // 模拟person中name和age的变化
  setTimeout(() => {
    state.person.name = 'Alice' // 输出'person changed: Alice 25'
    state.person.age = 30 // 输出'person changed: Alice 30'
  }, 1000)
</script>

打印:

三、与watch的区别

1. 监听方式不同watchEffect()是自动追踪所有使用的响应式数据,而watch需要手动指定要监听的特定属性。

2. 监听粒度不同watchEffect()监听的是响应式数据的整个变化,而watch可以侦听指定的属性或表达式的变化。

3. 计算属性处理方式不同:对于计算属性,watchEffect()会自动依赖于计算属性使用到的响应式数据,而watch需要手动指定计算属性为监听目标。

四、注意事项

1. 避免过度监听:由于watchEffect()会追踪使用到的所有响应式数据,因此要确保在回调函数中只使用必要的响应式数据,避免造成不必要的渲染开销。

2. 异步操作需谨慎处理:由于watchEffect()会立即执行回调函数,如果在回调函数中进行异步操作,需要谨慎处理,以免导致意外行为或副作用。

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

// 它会自动停止
watchEffect(() => {})

// ...这个则不会!
setTimeout(() => {
  watchEffect(() => {})
}, 100)
</script>

3. 避免无限循环:当在watchEffect()的回调中修改响应式数据时,可能会导致无限循环。要避免此问题,可以使用watch()函数并设置immediate: true选项,或者使用ref来存储临时数据。

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

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

相关文章

LeetCode 1183 矩阵中 1 的最大数量 (图解)

题目省略了 题解 很多题解都写的是&#xff0c;求正方形矩阵在原矩阵的等效位置的数量&#xff0c;但是不画图可能不好理解&#xff0c;比如我现在有个 3*3 的矩阵&#xff0c;需要用2*2的正方形填充 上图中我枚举了所有的点在小正方形可能出现的情况&#xff08;A、B、C、D&…

Appium-Python-Client 源码剖析 (一) driver 的元素查找方法

目录 前言 源码版本:0.9 结构图&#xff1a; mobileby.py appium 的 webdriver.py selenium 的 webdriver.py seleniumdriver appiumdriver 前言 Appium-Python-Client是一个用于Python语言的Appium客户端库&#xff0c;它提供了丰富的API和功能&#xff0c;用于编写和…

SpringBoot整合缓存(Caffeine、Redis)

SpringBoot整合缓存 注解介绍 EnableCaching 标记在CacheManager统一配置类&#xff0c;需要配合Configuration使用 Cachable 标记在需要使用缓存的实现类上&#xff0c;一般用于查询操作。当该方法输入参数对应的缓存数据不存在与缓存引擎中&#xff08;类似Redis&#x…

视频配音乐怎么制作?教你简单好用的配乐方法

在很多情况下&#xff0c;为视频配乐可以增强观众的情感体验&#xff0c;使观众更加投入到视频内容中。配乐可以增强视频的节奏和情感共鸣&#xff0c;使观众更容易理解和接受视频的信息。此外&#xff0c;配乐还可以为视频添加品味和风格&#xff0c;使其更具吸引力。教大家几…

人际关系处理文库 怎样与女人相处 怎样与领导相处 张胜利 岳贵安著 PDF 网盘免费...

人际关系处理文库-17部大全 怎样与男人相处、怎样与女人相处、怎样与领导相处、怎样对付小人、怎样识别谎言、怎样洞察人心、怎样变通协调、怎样出人头地、怎样对付难缠的人、怎样对付小报告、怎样广结人缘、怎样看穿陷阱、怎样笼络人心、怎样妙言善辩、怎样轻松自如、怎样善解…

Huggingface tokenizer decode batch_decode报错解决思路与分析

文章目录 摘要引出原因最初报错的解决办法batch_decode 源码decode 和 batch_decode 都可以成功运行的例子decode 和 batch_decode 不能同时成功运行的例子源码将输入转成 python list 摘要 本篇文章&#xff0c;由笔者最初遇到的decode报错开始&#xff0c;叙述笔者如何解决这…

继连续亏损后,软银依然下注机器人,今年能否在人工智能浪潮中分一杯羹?

原创 |文 BFT机器人 近日&#xff0c;将近7个月没露面的孙正义&#xff0c;现身软银集团年度股东大会并表示&#xff0c;软银目前账面现金有5万亿日元&#xff08;约合人民币2547亿元&#xff09;&#xff0c;已准备好将防守模式转变为进攻模式&#xff0c;All in AI&#xff…

imazing怎么导出app,Imazing修改APP存档的方法【2023详解】

相信很多小伙伴都不清楚Imazing导出APP及能够帮助我们更好地去管理手机&#xff0c;还能够替换从网上下载的游戏存档&#xff0c;让用户可以有一个更好地体验&#xff0c;那么具体要如何去操作呢&#xff1f;下面就跟着小编一起来看看Imazing修改APP存档的方法吧。 使用软件 iM…

修改windows文件没有权限

一、问题描述&#xff1a;有时候我们在修改windows文件时&#xff0c;提示没有修改权限。 二、解决方案 修改windows的hosts文件 为例

Android平台GB28181设备接入侧音频采集推送示例

技术背景​ GB/T28181是广泛应用于视频监控行业的标准协议规范&#xff0c;可以在不同设备之间实现互联互通。今天我们主要探讨Android平台的Audio采集部分。 先说如何拿到数据源&#xff0c;在Android平台上采集音频&#xff0c;常用的方式如下&#xff1a; 1. 使用MediaRe…

LeetCode206.反转链表

LeetCode206.反转链表 一、双指针法 这道题如果再定义一个新的链表&#xff0c;实现链表元素的反转&#xff0c;其实是对内存空间的浪费 我们只需要改变链表的next指针的指向&#xff0c;直接将链表反转 之前链表头节点是元素1&#xff0c;反转之后头节点是元素5&#xff0c;…

Qt与Web混合开发:实现双向通信

引言 在当今的软件开发中&#xff0c;将Qt和Web技术结合起来进行混合开发变得越来越流行。Qt作为强大的C框架&#xff0c;提供了丰富的图形界面和功能库&#xff0c;而Web技术则提供了灵活性和跨平台的优势。结合这两种技术&#xff0c;我们可以开发出功能强大、具有吸引力的应…

【电路原理学习笔记】第4章:能量与功率:4.2 电路中的功率

第4章&#xff1a;能量与功率 4.2 电路中的功率 电能转换成热能所产生的热量&#xff0c;通常是电流通过电路中的电阻而产生的不必要的副产品。然而&#xff0c;在某些情况下&#xff0c;产生热量是电路的主要目的&#xff0c;例如&#xff0c;电阻式加热器。 当有电流通过电…

NLP 开源形近字算法之相似字列表(番外篇)

需求 有时候我们并不是需要返回两个字的相似&#xff0c;而是需要返回一个汉字的相似列表。 实现思路 我们可以分别计算所有的汉字之间的相似度&#xff0c;然后保留最大的前100个&#xff0c;放在字典中。 然后实时查询这个字典即可。 实现方式 bihuashu_2w.txt 中我们主…

BUG解决Button类不能从UnityEngine.UI中引用

Button does not contain a definition for onClick and no accessible extension method onClick accepting a first argument of type Button could be found (are you missing a using directive or an assembly reference?) 一个非常奇葩的问题;突然!!!!! using UnityEn…

什么是低代码开发平台(apaas)?低代码开发平台的价值有哪些

手码6500字&#xff0c;带你快速看懂&#xff1a;什么是低代码开发平台&#xff08;apaas&#xff09;&#xff0c;低代码有哪些价值&#xff0c;以及低代码平台的使用逻辑和心得。 一、什么是低代码开发平台&#xff08;apaas&#xff09;&#xff1f; 低代码开发平台是一种a…

【C++ 学习记录】(一)--你好,C++

写在前面 工作需要&#xff0c;重学C&#xff0c;实在是太痛苦了&#xff0c;大二的时候应试就没学会&#xff01;&#xff01; 进入正题 1.编程是怎么回事 C在百科上的解释是一种静态数据类型检查 的、支持多种编程范式&#xff08;面向过程与面向对象等&#xff09;的通用…

BTP Integration Suite学习笔记 - (Unit3) Developing with SAP Integration Suite

BTP Integration Suite学习笔记 - (Unit1) Developing with SAP Integration Suite BTP Integration Suite学习笔记 - (Unit2) Developing with SAP Integration Suite 带着一个问题去学&#xff1a;明明可以直接访问一个后端系统的OData服务&#xff0c;为什么还要再多绕一道C…

UE学习记录02----UMG创建控件模板+事件分发器

官网4.27&#xff1a; 创建控件模板 | 虚幻引擎文档 (unrealengine.com) 使用UMG创建的每个 控件蓝图 都被视为 用户控件&#xff0c;其可在其他控件蓝图中重复使用和放置。 其视觉效果和脚本功能都将延续到该蓝图中。 利用某些蓝图脚本&#xff0c;可创建UI控件的运行方式或…

echarts——环形图

const value_ze 60 const value2_ze 30 var myChart echarts.init(document.getElementById(myChart)); var option {title: {text: 目标完成率,subtext: [{a|${value_ze}}, {b|%}].join(),itemGap: 10,textStyle: {fontSize: 14,color: #fff,fontWeight: 500},subtextStyl…