Vue Composition API之侦听器watch/watchEffect

news2024/11/25 2:25:10

目录

  • 概述
  • 实例解析
    • 1.watch侦听器的用法
      • 基本使用
      • 深层侦听器
      • 即时回调监听器
    • 2、watchEffect侦听器的用法·
    • 3 停止侦听器
  • 总结

概述

在日常的开发中,很多时候我们需要去对一些状态进行监听,比如当显示学生的成绩列表时,我们使用一个学生的学号student_num作为请求成绩的参数,如果没有监听机制,当学号student_num改变时,我们需要依赖用户的操作去刷新成绩。但是有了侦听器,我们可以通过侦听器去监听student_num,当其发生改变时,自动去执行成绩刷新的操作。省去了很多冗余的逻辑。在Vue中,侦听器主要有两个,watch和watchEffect。下文将主要介绍他们的用法和区别。

实例解析

1.watch侦听器的用法

基本使用

我们可以使用 watch 函数在每次响应式状态发生变化时触发回调函数,下面的代码中,我们监听一个name属性的值,使用一个输入框输入name的不同值,当name的值改变时触发回调,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>watch侦听器的使用</title>
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <div id="root"></div>
</body>
<script>
 const app = Vue.createApp({
    setup(props,context){
        const {ref,watch} = Vue;
        const name = ref('walt');
        // 具备懒加载
        // 参数可以拿到原始值和当前值
        // 用一个侦听器可以监听多个数据
        watch(name,(currentValue,prevValue)=>{
            console.log(currentValue,prevValue);
        })
        return {name}
    },
   template:
         `
          <div>
            <div>Name:<input v-model="name"></div>
          </div>
         `
 });    
 const vm = app.mount('#root');
</script>

运行结果:
在这里插入图片描述

从上面的代码中我们可以看到,传入的第一个参数name使用了ref包装,使其具有了响应式的属性,其实,watch 的第一个参数可以是不同形式的“数据源”:它不仅可以是一个 ref (包括计算属性)、还可以是一个响应式对象、一个 getter 函数、或多个数据源组成的数组,如下所示:

const x = ref(0)
const y = ref(0)

// 单个 ref
watch(x, (newX) => {
  console.log(`x is ${newX}`)
})

// getter 函数
watch(
  () => x.value + y.value,
  (sum) => {
    console.log(`sum of x + y is: ${sum}`)
  }
)

// 多个来源组成的数组
watch([x, () => y.value], ([newX, newY]) => {
  console.log(`x is ${newX} and y is ${newY}`)
})

注意:我们不能直接监听对象的属性,比如下列的做法是不对的

 // 不正确的写法
    setup(props,context){
        const {watch,reactive,toRefs} = Vue;
        const nameObj = reactive({name:'walt'});
        watch(nameObj.name,(currentValue,prevValue)=>{
            console.log(currentValue,prevValue);
        })
        const {name} = toRefs(nameObj)
        return {name} 
    }

如上面的代码所示,直接监听对象的属性是不行的,需要提供一个返回该属性的getter函数,正确的写法如下所示:

// 正确写法
   setup(props,context){
        const {watch,reactive,toRefs} = Vue;
        const nameObj = reactive({name:'walt'});
        watch(()=>nameObj.name,(currentValue,prevValue)=>{
            console.log(currentValue,prevValue);
        })
        const {name} = toRefs(nameObj)
        return {name} 
    }

深层侦听器

这里引用官网的例子解释, 直接给 watch() 传入一个响应式对象,会隐式地创建一个深层侦听器——该回调函数在所有嵌套的变更时都会被触发:

const obj = reactive({ count: 0 })

watch(obj, (newValue, oldValue) => {
  // 在嵌套的属性变更时触发
  // 注意:`newValue` 此处和 `oldValue` 是相等的
  // 因为它们是同一个对象!
})

obj.count++

相比之下,一个返回响应式对象的 getter 函数,只有在返回不同的对象时,才会触发回调:

watch(
  () => state.someObject,
  () => {
    // 仅当 state.someObject 被替换时触发
  }
)

我们可以添加deep :true,来将上面的例子转换成深层侦听器,代码如下:

watch(
  () => state.someObject,
  (newValue, oldValue) => {
    // 注意:`newValue` 此处和 `oldValue` 是相等的
    // *除非* state.someObject 被整个替换了
  },
  { deep: true }
)

需要注意的是,深层侦听器会遍历被侦听对象的嵌套属性,为了性能考虑,谨慎使用

即时回调监听器

watch 默认是懒执行的:仅当数据源变化时,才会执行回调。但在某些场景中,我们希望在创建侦听器时,立即执行一遍回调。比如,我们想请求一些初始数据,然后在相关状态更改时重新请求数据。
我们可以通过传入 immediate: true 选项来强制侦听器的回调立即执行,代码如下:

watch(source, (newValue, oldValue) => {
  // 立即执行,且当 `source` 改变时再次执行
}, { immediate: true })

2、watchEffect侦听器的用法·

watchEffect帧听器是立即执行的,它不像watch是懒加载的,而且它不需要传递要侦听的内容,会自动感知代码依赖,不需要传递很多参数,只需要传递一个回调函数就可以。引用Vue官网的例子,比如:当 todoId 的引用发生变化时使用侦听器来加载一个远程资源:

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 })

上面的todoId一次是作为源,另一次是在回调中使用的,可以用 watchEffect 函数 来简化上面的代码。watchEffect() 允许我们自动跟踪回调的响应式依赖。上面的侦听器可以重写为:

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

使用watchEffect,回调会立即执行,不需要指定 immediate: true。在执行期间,它会自动追踪 todoId.value 作为依赖(和计算属性类似)。每当 todoId.value 变化时,回调会再次执行。有了 watchEffect(),不再需要明确传递 todoId 作为源值

3 停止侦听器

停止侦听器

在 setup() 或 <script setup> 中用同步语句创建的侦听器,会自动绑定到宿主组件实例上,并且会在宿主组件卸载时自动停止。因此,在大多数情况下,不需要关心怎么停止一个侦听器。侦听器必须用同步语句创建:如果用异步回调创建一个侦听器,那么它不会绑定到当前组件上,必须手动停止,以防内存泄漏。如下方这个例子:

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

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

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

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

const stop= watchEffect(() => {})

// ...当该侦听器不再需要时
stop()

总结

至此,本文已经介绍完了watch和watchEffect帧听器的使用和注意点,最后总结下两个侦听器的区别,watch具备懒加载,参数可以拿到原始值和当前值,用一个侦听器可以监听多个数据;而watchEffect侦听器是立即执行的,不需要传递要侦听的内容,它会自动感知代码依赖,但是watchEffect无法获取改变之前的值

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

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

相关文章

【Python】循环语句 ④ ( for 循环 | for 循环基础语法 | 代码示例 - for 循环基础用法 | 代码示例2 - for 循环统计单词 )

文章目录 一、for 循环与 while 循环二、for 循环基础语法三、代码示例 - for 循环基础用法三、代码示例2 - for 循环统计单词 一、for 循环与 while 循环 for 循环 与 while 循环 可以 f实现 相同的 循环功能 , 二者有如下区别 : 循环条件不同 : while 循环 的 循环控制条件 …

C++学习笔记(四): 类、头文件、对象

一个类定义了一个类型&#xff0c;以及与其关联的一组操作。 类机制是C最重要的特性之一。实际上&#xff0c;C最初的一个设计焦点就是能定义使用上像内置类型一样自然的类类型&#xff08;class type&#xff09;。 #include <iostream>using namespace std;class Box …

撰写博客如何获得持续的关注和支持

完成一篇如何获得铁粉&#xff0c;或者相关的文章且质量分达到80分以上即可 最近的博客都是在AI主导下完成的&#xff0c;大数据和大模型的优势的确有不可取代的强大优势&#xff0c;这种优势超过了撰写8年博客加入CSDN18年所有经验和努力的总和。 是的&#xff0c;AI和大数据的…

IPv4 和 IPv6 的特点、区别以及在互联网中的应用

在当今互联网时代&#xff0c;IP 地址是连接和通信的基础。IPv4&#xff08;Internet Protocol version 4&#xff09;和 IPv6&#xff08;Internet Protocol version 6&#xff09;是两种常见的 IP 地址版本。IPv4 是最早广泛使用的 IP 地址协议&#xff0c;而 IPv6 则是 IPv4…

chatgpt赋能python:Python循环结束的方式

Python循环结束的方式 在Python编程中&#xff0c;循环是一个非常重要的概念。循环是在程序中重复执行一段代码的方法。当满足特定条件时&#xff0c;循环可以继续执行&#xff0c;否则循环将结束。循环包括while循环和for循环两种方式。 while循环结束的方式 while循环是Py…

chatgpt赋能python:Python彩色输出:让代码更加生动有趣

Python 彩色输出&#xff1a;让代码更加生动有趣 如果你是一名Python程序员&#xff0c;那么你一定知道代码的可读性有多么重要。合理的排版和注释代码可以使你的代码更易于理解&#xff0c;但有时候你需要一些额外的工具来使代码更加生动有趣。这时候&#xff0c;Python 的彩…

腾讯云CVM服务器端口怎么开通?以开80端口为例

腾讯云CVM服务器端口是通过配置安全组规则来开通的&#xff0c;阿腾云以开通80端口为例来详细说下腾讯云轻量应用服务器开启端口的方法&#xff0c;其他的端口的开通如8080、1433、443、3306、8888等端口也适用于此方法&#xff0c;腾讯云服务器开通端口教程如下&#xff1a; …

chatgpt赋能python:Python取数字:一种简单而强大的方法

Python取数字&#xff1a;一种简单而强大的方法 Python是一种高级编程语言&#xff0c;被广泛用于数据分析、人工智能、Web开发等领域。在这个强大的语言中&#xff0c;我们可以使用非常简单的方法来提取数字&#xff0c;无论是从文本文件、数据库中&#xff0c;还是从互联网上…

新的交互流程:Ambire dApp 目录为Web3 的流畅旅程保驾护航

Ambire 钱包现在将 dApps 列入白名单&#xff0c;以提供丝滑又安全的用户体验。 尊敬的 Ambire 家人们&#x1f64c;&#xff0c;你们好&#xff01; 我们很高兴能与大家正式分享我们的 dApp 目录和插件系统 &#x1f389;。 你们中的一些人可能已经在你们的 Ambire 账户中注意…

chatgpt赋能python:Python坐标图:简单易用的数据可视化工具

Python 坐标图&#xff1a;简单易用的数据可视化工具 作为一种通用工具&#xff0c;Python 不仅在数据科学、自然语言处理、机器学习和深度学习等领域应用广泛&#xff0c;还在数据可视化方面表现出色。Python 的数据可视化库丰富多样&#xff0c;其中最受欢迎的就是 Matplotl…

chatgpt赋能python:Python微信群:一起探讨Python大家庭

Python 微信群&#xff1a;一起探讨Python大家庭 Python 微信群是一个由 Python 爱好者组成的大家庭&#xff0c;他们在这个平台上分享、交流、学习Python知识。在这个微信群中&#xff0c;你可以认识来自各行各业的Python工程师&#xff0c;可以发问、分享自己的经验和学习进…

GcExcel v6.1 支持新的 ‘.sjs‘ 模板文件 ‘.xltx‘ 格式 Crack

GrapeCity Documents for Excel (GcExcel) v6.1 版本现已上线&#xff01;该版本支持新的 SpreadJS .sjs 文件格式和 Excel 模板文件 .xltx 格式。此外&#xff0c;GcExcel 支持更多的SpreadJS兼容性功能和对 GcDataViewer 的多项增强。看看下面的主要亮点。 导入/导出 Spread…

chatgpt赋能python:Python循环两次:多次复制代码的快捷方式

Python 循环两次&#xff1a;多次复制代码的快捷方式 如果你是一名Python工程师&#xff0c;你可能已经会用循环复制代码了。然而&#xff0c;你是否知道可以循环两次来一次性复制代码呢&#xff1f;在这篇文章里&#xff0c;我们将介绍循环两次的方法&#xff0c;以及如何在代…

【分布族谱】均匀分布和三角形分布的关系

文章目录 均匀分布和三角分布均匀分布相加对数均匀分布 均匀分布和三角分布 均匀分布是最容易理解的连续随机分布&#xff0c;实际上就是等概率的连续分布&#xff0c;其PDF为 f ( x ) 1 b − a , x ∈ ( a , b ) f(x)\frac{1}{b-a}, x\in (a,b) f(x)b−a1​,x∈(a,b) 其样本…

chatgpt赋能python:Python嵌入-提高网站性能的最佳实践

Python 嵌入 - 提高网站性能的最佳实践 作为一名有10年Python编程经验的工程师&#xff0c;我想向大家介绍一下Python嵌入的概念以及如何将它应用于提高网站的性能。 什么是 Python 嵌入&#xff1f; Python嵌入是将Python解释器嵌入到其他应用程序中的过程。当Python解释器…

LOTL网络攻击技术越来越受欢迎

根据 APJ Darktrace 企业安全总监对 ACSC 及其五眼联盟合作伙伴本周发布的声明的回应&#xff0c;“离地生活”攻击技术越来越受欢迎。 Living off the land (LOTL) 是一种无文件恶意软件或 LOLbins 网络攻击技术。 网络罪犯使用受害人系统中的本机合法工具来维持和推进攻击。…

chatgpt赋能python:Python字段截取入门指南

Python字段截取入门指南 在Python中&#xff0c;对于字符串和列表等容器类型的对象&#xff0c;经常需要对其中的字段或元素进行截取。本篇文章将为您介绍Python中常用的字段截取方法&#xff0c;并提供一些示例&#xff0c;让您快速上手。 字符串字段截取 从头开始截取 如…

chatgpt赋能python:Python坐标转换:从经纬度到UTM

Python 坐标转换&#xff1a; 从经纬度到UTM Python 是一种高级编程语言&#xff0c;它在数据科学和地理信息系统领域中越来越受欢迎。在本文中&#xff0c;我们将讨论如何使用 Python 进行坐标转换&#xff0c;特别是从经纬度到 UTM&#xff08;通用横轴墨卡托投影&#xff0…

chatgpt赋能python:Python小数进位:从保留小数点后几位到基数进位

Python 小数进位&#xff1a;从保留小数点后几位到基数进位 Python 是一种易学易用的编程语言&#xff0c;特别适合初学者和专业工程师。它不仅支持整数和浮点数等基本数据类型&#xff0c;还提供了许多有用的内置函数和模块&#xff0c;其中包括浮点数进位方法和库。 本文将…

chatgpt赋能python:Python如何安装软件包

Python如何安装软件包 Python是一种广泛使用的编程语言&#xff0c;因其易学易用和灵活性而受到了许多程序员的欢迎。在Python中&#xff0c;安装各种软件包是必不可少的。本文章将向您介绍如何使用Python安装软件包。 什么是软件包&#xff1f; 在Python中&#xff0c;软件…