vue3中的watch可能是比watchEffect更好的选择

vue3中的watch可能是比watchEffect更好的选择

vue 最强大的功能之一是能够根据基本数据的变化来执行响应式副作用。为此,vue3提供两个方法:watchwatchEffect 。虽然两个方法都可以监控响应式数据的变化,但他们有不同的使用方式和行为。本文将探讨它们之间的差异以及何时使用它们。

watch

watch 方法允许我们观察一个或多个响应式数据源,并在有更新时调用回调函数。

语法虽然与vue2有所不同,但它的工作原理vue2相同的:

import { watch } from 'vue'
watch(source, callback, options?)

watch()方法接受3个参数:

  • source:响应式数据。响应式数据可能是从以下几种数据中获取到的:

    1. getter方法或者computed方法返回的值
    2. 一个ref数据
    3. 一个reactive数据
    4. 一个包含了上面任意数据的数组
  • callback:回调函数,当源数据更改时会调用的函数,该回调函数接受以下几个参数:

    • value:观察数据的新状态
    • oldValue:观察数据的旧状态
    • onCleanup:一个可以用来注册清理回调的函数。清理回调将在下次重新运行效果之前调用,并可用于清理无效的副作用,例如一个未解决的异步请求。
  • options:可选配置,包含下列字段:

    • immediate:一个布尔值,指示是否应该在观察器创建时立即触发回调,此时oldValueundefined
    • deep:一个布尔值,指示是否要执行源数据的深遍历。如果它是一个对象的话,那么回调就会启动深度监听。查看深度监听
    • flush:表示如何调整回调时间的字符串。查看回调刷新时间
    • onTrack / onTrigger:当观察器的依赖项被触发时调试它们的功能。查看观察者调试

watch() 功能默认是懒触发,这意味着只有在监听的源数据改变时才调用回调。

当监听多个源数据时,回调接收两个数组,其中包含与源数组对应的新旧值。

watchEffect相比,watch 使我们能够:

  • 懒触发副作用
  • 更具体根据什么状态去定义、触发观察者重新运行
  • 访问被监视状态的先前值和当前值。

示例

监听一个getter

const state = reactive({ count: 0 })
watch(() => state.count,(count, prevCount) => {console.log(count, prevCount)}
)

监听一个ref

const count = ref(0)
watch(count, (count, prevCount) => {console.log(count, prevCount)
})

当查看多个源时,回调接收到包含源数组相应的新旧值的数组:

watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => {console.log("New values:" , foo, bar)console.log("Old values:" , prevFoo, prevBar)
})

WatchEffect

watchEffect 会立刻运行一个回调函数和自动追踪它的被动依赖关系。当任何反应依赖项发生变化时,都会执行回调函数。

import { reactive, watchEffect } from "vue"const state = reactive({count: 0,name: 'Leo'
})watchEffect(() => {// 立即执行// Count: 0, Name: Leoconsole.log(`Count: ${state.count}, Name: ${state.name}`)
})state.count++ // Count: 1, Name: Leo
state.name = 'alex' // Count: 1, Name: alex

在上面的例子中,我们使用watchEffect来监听状态、计数和名称属性的更改。每当它们中的任何一个更改回调函数都会记录当前的计数值和名称值。

第一次watchEffect 调用时,立即执行回调函数,使用当前的计数和名称值。在此之后,当任何反应依赖项(计数或名称)更改时,将重新运行回调函数。

就像watch一样,watchEffect 也有一些额外的功能使它更加强大。我们可以通过一个选项对象作为配置观察者行为的第二个参数。例如,可以指定flush timing (当观察者被执行时) 或者添加一个调试钩子。

回调函数的第一个参数为onCleanup 这个特殊的函数时,可以使用此函数来注册将在重新执行监视器之前调用的清理回调。这有助于清理不再需要的资源。

import { ref, watchEffect } from "vue"const id = ref(1)
const data = ref(null)watchEffect(async (onCleanup) => {const { response, cancel } = await fetch(`https://example.com/api/data/${id.value}`)onCleanup(cancel)data.value = response.data
})

在上面的例子中,我们使用watchEffectID属性更改时从API中获取数据。我们使用onCleanup 功能注册一个取消功能,如果ID属性在请求完成之前更改,该功能将取消获取请求。

另外,我们可以使用watchEffect 去阻止监听。

import { watchEffect } from "vue"const stop = watchEffect(() => {// …
})
// Stop the watcher
stop()

另一个令人困惑的问题是watchEffect 仅在同步执行期间跟踪依赖关系。在第一个等待项之前访问的所有属性将在使用一个异步回调时被跟踪,但之后的所有属性不会被跟踪。

<script setup>
import { reactive, watchEffect } from "vue"const state = reactive({count: 0,name: 'Leo'
})const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));watchEffect(async () => {console.log(`Count: ${state.count}`) // This will be trackedawait sleep(200)console.log(`Name:  ${state.name}`)  // This will NOT be tracked
})</script><template>
<input type="number" v-model="state.count" />
<br />
<input v-model="state.name" />
</template>

await 之前的一切(即state.count )将被追踪。
await 之后的一切(即state.name )不被追踪。

总结

watchwatchEffect 两者都允许我们以响应式方式执行副作用,但它们在如何跟踪依赖性方面有所不同:

  • watch 只追踪显式监视源,不会跟踪回调中的任何访问。此外,回调只在源实际发生更改时触发。把依赖追踪和副作用分开,当回调运行时watch 提供更精确的控制。
  • watchEffect将依赖追踪和副作用结合到一个阶段。在同步执行期间,它自动跟踪所访问的每个响应式属性。这将导致更简洁的代码,但使得它的被动依赖性不那么明确。

如果我们需要查看嵌套数据结构中的几个属性,watchEffect() 可能比深度监视器更有效,因为它只跟踪回调中使用的属性,而不是递归跟踪所有的属性。

watch能确保更好的总体控制,区分依赖跟踪和副作用,避免意外造成性能下降。

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

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

相关文章

Go语言中的自定义函数类型

函数类型的基本概念 在Go语言中&#xff0c;函数类型是一种将函数作为值的数据类型。与其他类型一样&#xff0c;函数类型可以被声明、赋值给变量&#xff0c;作为参数传递和作为返回值返回。通过函数类型&#xff0c;我们可以将函数看作一种可执行的对象&#xff0c;对其进行…

asp.net企业生产管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

一、源码特点 asp.net 企业生产管理系统 是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库为sqlserver2008&#xff0c;使用c#语 言开发 二、功能介绍 (1)用户管理&…

Spring学习笔记11 GoF代理模式

Spring学习笔记10 JdbcTemplate_biubiubiu0706的博客-CSDN博客 新建个maven模块 static-proxy 演示静态代理 订单接口 测试 需求:统计每个业务方法的耗时 package com.example.proxy.service;/*** author hrui* date 2023/9/25 8:42*/ public class OrderServiceImpl implem…

分布式网络在移动医疗场景中的应用

随着医疗信息化建设实践的深入&#xff0c;越来越多的医疗机构开始借助网络信息技术改善其运营及管理模式&#xff0c;为患者提供更高质量、更高效率、更加安全体贴的医疗服务。移动医疗便是在此背景下产生的新业务需求。 常见的移动医疗场景 住院部&#xff1a;移动查房、智…

Java案例:判断质数

需求&#xff1a;键盘录入一个数&#xff0c;判断是否是质数 分析&#xff1a;从2到number-1开始循环&#xff0c;判断是否有数字能被number整除 import java.util.Scanner;public class demo {public static void main(String[] args){Scanner sc new Scanner(System.in);S…

使用JavaScript将数字格式化成千分位的n种方法

1,使用数组方法: 1) 数字转字符串,字符串按照小数点.分割 2) 整数部分拆分成字符串数组,并倒叙 3) 遍历, 按照每三位添加逗号,号 4) 拼接整数部分小数部分 function format_width_array(number) { // 将数字转换为千分位字符串const arr String(number).split(.);// 整数…

代码阅读分析神器-Scitools Understand

这里写目录标题 前言概要功能介绍1.代码统计2.图形化分析3.代码检查 使用方法下载及使用 前言 作为一名程序员&#xff0c;阅读代码是一个必须要拥有的能力&#xff0c;但无奈很多代码逻辑嵌套非常多&#xff0c;看起来非常吃力&#xff0c;看了那段逻辑就忘记了刚才的逻辑&am…

SpringBoot 集成 AKKA

文章目录 应用场景与 SpringBoot 集成示例 应用场景 AKKA 是一个用于构建高并发、分布式和容错应用程序的开源框架。它基于Actor模型&#xff0c;提供了强大的并发抽象和工具&#xff0c;适用于各种业务场景。以下是一些使用AKKA框架的常见业务场景的示例&#xff1a; 实时数据…

WordPress还原重置插件WP Reset 教程!

这是一篇完整的 WordPress 还原教程&#xff0c;我们将使用一款插件&#xff0c;快速重置整个 WordPress 网站。 有时在安装不同主题、网站插件后&#xff0c;可能会导致程序码彼此的冲突&#xff0c;而让网站出现跑版、错误等 ..&#xff0c;这时直接重新来过可能反而比较快一…

大模型从入门到应用——LangChain:代理(Agents)-[代理执行器(Agent Executor):处理解析错误、访问中间步骤和限制最大迭代次数]

分类目录&#xff1a;《大模型从入门到应用》总目录 LangChain系列文章&#xff1a; 基础知识快速入门 安装与环境配置链&#xff08;Chains&#xff09;、代理&#xff08;Agent:&#xff09;和记忆&#xff08;Memory&#xff09;快速开发聊天模型 模型&#xff08;Models&…

AM@映射@函数@反函数@复合函数

文章目录 abstract直接定义函数的定义反函数定义复合函数定义 基于映射定义映射像原像定义域值域小结例满射单射&#x1f47a;双射映射的其他称呼 逆映射复合映射映射间可复合条件复合顺序 函数基于映射的函数相关定义函数函数的记法及其含义函数值 f ( x ) f(x) f(x)函数关系 …

使用Http Interface客户端解析text/html类型参数

前言 Spring6和Spring Boot3的正式发布也有一段时间了&#xff0c;最低支持的java版本也是直接跳到了17。而且最近java21也出来了&#xff0c;作为一个javaer&#xff0c;你不会还在坚守java8吧&#xff1f; Http Interface是Spring6新推出的一个声明式http客户端&#xff0c;…

命令执行(rce)

1.命令与代码执行原理 命令执行原理 参数给变量未经过滤&#xff0c;直接使用了不安全的函数处理了变量 127.0.0.1&&ipconfig 有漏洞 常用的函数 assert,system,exec,shell_exec, eval,(反单引号&#xff09; 代码执行原理 参数给变量未经过滤&#xff…

56块钱搭建一个ubuntu 2204 linux 服务器

硬件pdd上淘的一个linux小盒子 应该是以前的机顶盒之类的 实物图如下 今天刚收到小盒子 找了个显示器 键盘 查到小盒子上通电 本来指示灯应该亮的 老板刷机之后 led灯都不亮了 不知道有没有开机 我还以为坏了 刚开始 然后直接连到显示器上 有输出 那说明没问题…

【C语言】进阶——结构体+枚举+联合

①前言&#xff1a; 在之前【C语言】初阶——结构体 &#xff0c;简单介绍了结构体。而C语言中结构体的内容还有更深层次的内容。 一.结构体 结构体(struct)是由一系列具有相同类型或不同类型的数据项构成的数据集合&#xff0c;这些数据项称为结构体的成员。 1.结构体的声明 …

Ubuntu 安装PostgreSQL

网上有各种版本的&#xff0c;也可以去官网看官方的文档。我是下载的PostgreSQL-11.4版本的。找到以后直接复制网上的压缩包链接就可以。 $ mkdir /opt/postgresql && cd /opt/postgresql $ wget https://ftp.postgresql.org/pub/source/v11.4/postgresql-11.4.tar.gz…

智算引领·创新未来 | 2023紫光展锐泛物联网终端生态论坛成功举办

9月21日&#xff0c;紫光展锐在深圳成功举办2023泛物联网终端生态论坛。论坛以“智算引领创新未来”为主题&#xff0c;吸引了来自信通院、中国联通、中国移动、中国电信、金融机构、终端厂商、模组厂商等行业各领域三百多位精英翘楚汇聚一堂&#xff0c;探讨在连接、算力驱动下…

数据结构学习笔记——查找算法中的树形查找(平衡二叉树)

目录 一、平衡二叉树的定义二、平衡因子三、平衡二叉树的插入和构造&#xff08;一&#xff09;LL型旋转&#xff08;二&#xff09;LR型旋转&#xff08;三&#xff09;RR型旋转&#xff08;四&#xff09;RL型旋转 四、平衡二叉树的删除&#xff08;一&#xff09;叶子结点&a…

初学vue.js

准备Vue.js环境 ① 下载环境&#xff1a; javaScript语言的程序包&#xff1a;外部js文件 对于Vue来说&#xff0c;导入Vue的外部js文件就能够使用Vue框架了。 Vue框架的js文件获取: 官网提供的下载地址&#xff1a;https://cdn.jsdelivr.net/npm/vue/dist/vue.js ②导入环境…

短视频矩阵系统,短视频矩阵源码技术

1、抖音开放平台申请账号&#xff0c;快手平台申请账号&#xff1b;阿里云混剪接口。 2、系统总台支持OEM代理&#xff0c;可以按点数管理。 3、代理功能。包括是否允许再次开二级代理、是否允许OEM等。 4、可支持一条龙搭建服务&#xff0c;抖音平台开放平台代申请等 开发…