在 Vue 3 中,watchEffect 是一个用于监听响应式数据变化的 API。它可以在函数内部自动跟踪数据的依赖,并在依赖变化时重新运行函数。

watchEffect 的作用以及各个参数的功能讲解:

watchEffect(effect: (onInvalidate: InvalidateCbRegistrator) => void | (() => void) | Promise<void>, options?: WatchEffectOptions): WatchStopHandle

    • effect:要监听的响应式数据以及需要执行的副作用函数。effect 函数接收一个 onInvalidate 回调函数作为参数,用于在 effect 的依赖发生变化时执行清理函数。effect 函数可以返回一个清理函数,也可以返回一个 Promise,Promise 完成时执行的函数也会被视为清理函数。如果 effect 函数中使用的数据没有在响应式对象中被引用,那么 watchEffect 不会监听到这些数据的变化。
    • options:监听选项对象,可选。可以用来配置监听的行为,例如 deepflush 等选项。具体的选项请参考下面的讲解。
    • 返回值:一个函数,调用它可以停止监听。

WatchEffectOptions

    watchEffect 函数接受一个可选的选项对象,用于配置监听行为。以下是 WatchEffectOptions 对象的属性及其功能:

    • lazy:是否延迟执行 effect 函数。如果设置为 true,则在首次调用 watchEffect 时不会执行 effect 函数,只有在其依赖发生变化时才会执行。默认为 false
    • deep:是否深度监听对象和数组的变化,默认为 false。如果设置为 true,则会递归监听对象和数组中的所有属性。
    • flush:何时执行回调函数。默认为 'pre',表示在响应式数据变化后立即执行回调函数,但在同一事件循环中的其他变化不会触发回调函数。如果设置为 'post',则会在同一事件循环中的所有变化都发生后执行回调函数。

例如,以下代码使用 watchEffect 监听 message 的变化,并在变化时执行回调函数。

import { watchEffect } from 'vue';

watchEffect(() => {
console.log(`message 变为 ${message}`);
});

下面是一个简单的例子,演示了如何使用 watchEffect 监听响应式数据变化:

<template>
<div>
<p>输入框的值为:{{ message }}</p>
<input v-model="message" />
</div>
</template> <script>
import { defineComponent, ref, watchEffect } from 'vue'; export default defineComponent({
setup() {
const message = ref(''); watchEffect(() => {
console.log(`message 值改变为:${message.value}`);
}); return {
message
};
}
});
</script>

在这个例子中,我们使用 ref 函数定义了一个名为 message 的响应式数据,并将其初始化为空字符串。我们使用 watchEffect 函数监听 message 的变化,并在函数内部打印出 message 的值。因为 watchEffect 函数会自动跟踪 message 的依赖,所以当用户在输入框中输入内容时,watchEffect 函数就会重新运行,打印出新的 message 值。

需要注意的是,watchEffect 函数的回调函数不需要显式地指定依赖项,它会自动跟踪回调函数内部使用到的所有响应式数据。因此,当你使用 watchEffect 函数时,不需要再使用 watch 函数或 computed 函数来监听数据变化。但是,如果你需要监听某个特定的响应式数据变化,可以在回调函数中使用该数据,这样 watchEffect 就会自动跟踪它。

watchEffect 函数的返回值是一个用于停止监听的函数。当你调用这个函数时,watchEffect 就会停止监听响应式数据的变化。

以下是一个示例,演示如何使用 watchEffect 函数的返回值停止监听:

<template>
<div>
<p>输入框的值为:{{ message }}</p>
<button @click="stopWatching">停止监听</button>
<input v-model="message" />
</div>
</template> <script>
import { defineComponent, ref, watchEffect } from 'vue'; export default defineComponent({
setup() {
const message = ref(''); const stopWatching = watchEffect(() => {
console.log(`message 值改变为:${message.value}`);
}); function stopWatching() {
stopWatching();
} return {
message,
stopWatching
};
}
});
</script>

在这个例子中,我们定义了一个名为 stopWatching 的函数,它调用了 watchEffect 函数的返回值,从而停止了监听。我们在模板中添加了一个按钮,当用户点击它时,就会调用 stopWatching 函数,从而停止监听 message 的变化。

watch的作用以及各个参数的功能讲解:

watch 是 Vue 3 中用于监听响应式数据变化的 API,它能够在响应式数据发生变化时执行回调函数。以下是 watch 函数的参数及其功能:

  1. watch(source: string | Function | Ref, callback: Function, options?: WatchOptions): WatchStopHandle
  • source:要监听的响应式数据,可以是一个字符串(表示要监听的数据在组件实例中的属性名)、一个函数(返回要监听的数据)或一个 ref 对象。
  • callback:响应式数据变化时要执行的回调函数。回调函数接收两个参数:新值和旧值。
  • options:监听选项对象,可选。可以用来配置监听的行为,例如 deepimmediate 等选项。具体的选项请参考下面的讲解。
  • 返回值:一个函数,调用它可以停止监听。
  1. WatchOptions

watch 函数接受一个可选的选项对象,用于配置监听行为。以下是 WatchOptions 对象的属性及其功能:

  • immediate:是否在监听开始时立即执行回调函数,默认为 false
  • deep:是否深度监听对象和数组的变化,默认为 false。如果设置为 true,则会递归监听对象和数组中的所有属性。
  • flush:何时执行回调函数。默认为 'pre',表示在响应式数据变化后立即执行回调函数,但在同一事件循环中的其他变化不会触发回调函数。如果设置为 'post',则会在同一事件循环中的所有变化都发生后执行回调函数。
  • onTrack:监视属性被访问的函数。它接收一个追踪对象(TrackOpTypes)和追踪的目标对象(target)。可以用它来进行依赖追踪分析等操作。
  • onTrigger:监视属性被修改的函数。它接收一个触发对象(TriggerOpTypes)和触发的目标对象(target)。可以用它来进行调试、性能分析等操作。
  • 例如,以下代码监听 message 的变化,并在变化时执行回调函数,同时设置 immediate 选项为 true,表示在组件挂载时立即执行一次回调函数。

import { watch } from 'vue';

watch(
() => message, // 要监听的响应式数据
(newValue, oldValue) => {
console.log(`message 从 ${oldValue} 变为 ${newValue}`);
},
{
immediate: true // 在组件挂载时立即执行回调函数
}
);

watchEffectwatch 都是 Vue 3 中用于监听响应式数据变化的 API,它们之间的主要区别在于回调函数的类型和依赖项的声明方式。

  • watchEffect 接收一个不带参数的函数作为回调函数,在函数内部使用到的响应式数据变化时会自动触发回调函数。watchEffect 会自动追踪响应式数据的变化,并在每次变化时重新运行回调函数。
  • watch 接收两个参数:第一个参数是要监听的响应式数据,第二个参数是一个回调函数。回调函数接收两个参数:新值和旧值。在响应式数据变化时,watch 会调用回调函数,并传入新值和旧值。可以通过第三个参数来声明要监听的选项,例如 deepimmediate 等。

因为 watchEffect 自动追踪响应式数据的变化,所以它更适合处理简单的数据逻辑。如果需要监听特定的响应式数据或使用更高级的选项,可以使用 watch 函数。使用 watch 函数需要显式声明要监听的响应式数据,这可以使代码更具可读性。此外,watch 函数还支持声明多个要监听的响应式数据,这使得它可以处理更复杂的数据逻辑。

总之,如果你只需要监听一些简单的响应式数据变化,可以使用 watchEffect 函数。如果需要监听特定的响应式数据或使用更高级的选项,可以使用 watch 函数。

以下是一个示例,演示 watchEffectwatch 的差别:

<template>
<div>
<p>message1 值为:{{ message1 }}</p>
<p>message2 值为:{{ message2 }}</p>
<button @click="increment">增加 message1 和 message2 的值</button>
</div>
</template> <script>
import { defineComponent, ref, watchEffect, watch } from 'vue'; export default defineComponent({
setup() {
const message1 = ref(0);
const message2 = ref(0); // watchEffect 自动追踪响应式数据的变化
watchEffect(() => {
console.log(`message1 值变为 ${message1.value}`);
}); // watch 需要显式声明要监听的响应式数据
watch(message2, (newValue, oldValue) => {
console.log(`message2 从 ${oldValue} 变为 ${newValue}`);
}); function increment() {
message1.value++;
message2.value++;
} return {
message1,
message2,
increment
};
}
});
</script>

在这个例子中,我们声明了两个响应式数据 message1message2,并分别使用了 watchEffectwatch 监听它们的变化。watchEffect 自动追踪 message1 的变化,并在变化时触发回调函数。而 watch 则需要显式声明要监听的 message2,并在它的变化时触发回调函数。在点击按钮时,我们同时增加了 message1message2 的值,从而触发了相应的回调函数。

watchEffectwatch 的区别在于,watchEffect 监听的是一个函数的副作用,而 watch 监听的是一个具体的响应式数据,因此 watchEffect 不需要显式指定监听的数据,它会自动检测 effect 函数中使用的响应式数据,并在其发生变化时执行回调函数。此外,watchEffect 也不需要手动停止监听,它会在组件卸载时自动停止监听。但是,watchEffect 不支持监听选项对象中的 immediateonTrackonTrigger 属性。

如果watch的监听对象是数组:

如果 watch 监听的是一个数组,则可以使用 deep 选项来深度监听数组元素的变化。当 deeptrue 时,watch 会递归监听数组中每个元素的变化。

例如,以下代码使用 watch 监听 list 数组的变化,并在变化时执行回调函数。

import { watch } from 'vue';

watch(
() => list,
(newList, oldList) => {
console.log('list 变化了', newList, oldList);
},
{ deep: true }
);

在上面的代码中,watch 监听的是一个计算属性,计算属性返回 list 数组。由于在监听选项中设置了 deep: true,因此 watch 会深度监听 list 数组,即递归监听数组中每个元素的变化。

注意,当使用 deep 选项监听数组时,如果数组中的元素是对象,则需要确保这些对象是响应式的,否则无法监听它们的变化。如果数组中的元素不是响应式的对象,则无法监听其变化。

vue全家桶进阶之路32:Vue3 WatchEffect和watch 监听的更多相关文章

  1. Vue 全家桶 + Electron 开发的一个跨三端的应用

    代码地址如下:http://www.demodashi.com/demo/11738.html GitHub Repo:vue-objccn Follow: halfrost · GitHub 利用 ...

  2. Vue全家桶高仿小米商城

    大家好,我是河畔一角,时隔半年再次给大家带来一门重量级的实战课程:<Vue全家桶高仿小米商城>,现在很多公司都在参与到商城的构建体系当中,因此掌握一套商城的标准开发体系非常重要:商城的开始 ...

  3. vue证明题一,vue全家桶的构成

    简单说下vue的构成,当然是简单为主,网上这东西满天飞,简单说几句就ok 1.vue是什么 vue读作view,是一种js框架.只关注于视图层,操作内容包括js,html,css 2.vue全家桶是什 ...

  4. 用 Vue 全家桶二次开发 V2EX 社区

    一.开发背景 为了全面的熟悉Vue+Vue-router+Vuex+axios技术栈,结合V2EX的开放API开发了这个简洁版的V2EX. 在线预览 (为了实现跨域,直接npm run dev部署的, ...

  5. Vue全家桶

    简介 “简单却不失优雅,小巧而不乏大匠”. Vue.js 是一个JavaScriptMVVM库,是一套构建用户界面的渐进式框架.它是以数据驱动和组件化的思想构建的,采用自底向上增量开发的设计. 为什么 ...

  6. 从零开始系列之vue全家桶(3)安装使用vuex

    什么是vuex? vuex:Vue提供的状态管理工具,用于同一管理我们项目中各种数据的交互和重用,存储我们需要用到数据对象. 即data中属性同时有一个或几个组件同时使用,就是data中共用的属性. ...

  7. 使用vue全家桶制作博客网站

    前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用vue全家桶制作的博客网站 概述 该项目是基于vue全家桶(vue.vue-router.vuex.v ...

  8. 转载: 使用vue全家桶制作博客网站 HTML5 移动网站制作的好教程

    使用vue全家桶制作博客网站   前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用vue全家桶制作的博客网站 概述 该项目是基于vue全家桶(vue. ...

  9. Vue全家桶介绍

    一直不清楚全家桶是什么玩意,上网搜了一下,才知道就是平时项目中使用的几个依赖包,下面分享一下 Vue 全家桶介绍 Vue有著名的全家桶系列,包含了vue-router(http://router.vu ...

  10. 一个简单的假vue全家桶(vue+vue-router+require)

    首先说明我觉得这是一个比较好理解的vue全家桶(虽然是假的),模块化也是用require来做的,而且如果后期有必要压缩我也会用gulp来做 1.依赖个个本地模块,require只是用来载入page,这 ...

随机推荐

  1. Java8-聚合操作

    Java聚合操作(Aggregate Operations)是对一堆数据进行处理的新的操作方法,我们知道,如果想对一堆数据进行处理,比如一个List对象中的数据进行处理,传统的操作就是遍历List数据 ...

  2. Android笔记--案例:找回密码

    找回密码 具体实现: 登录成功: 报告密码不同: 报告验证码错误: 代码相关: 找回密码的界面很简单,不细说了,直接写就行 找回密码的逻辑实现: 下一次就去写数据存储啦! 拜拜!

  3. 11.1/2 鼠标显示问题(harib08a)11.2 实现画面外的支持(harib08b)

    ps:能力有限,若有错误及纰漏欢迎指正.交流 11.1 鼠标显示问题(harib08a) 存在问题: ​ 在harib07d中鼠标移动到最右侧后就不能再往右移了 解决办法: 将 if (mx > ...

  4. odoo 开发入门教程系列-模型和基本字段

    模型和基本字段 在上一章的末尾,我们创建一个odoo模块.然而,此时它仍然是一个空壳,不允许我们存储任何数据.在我们的房地产模块中,我们希望将与房地产相关的信息(名称(name).描述(descrip ...

  5. 拒绝“爆雷”!GaussDB(for MySQL)新上线了这个功能

    摘要:智能把控大数据量查询,防患系统奔溃于未然. 本文分享自华为云社区<拒绝"爆雷"!GaussDB(for MySQL)新上线了这个功能>,作者:GaussDB 数据 ...

  6. 导致sql注入的根本原因

    导致sql注入的根本原因 1.sql注入的定义 SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在 ...

  7. [Linux]常用命令之【top/uptime/w/vmstat/free】

    1 top 语法:top [-s time] [-d count] [-q] [-u] [-h] [-n number] [-f filename] -s time 设置屏幕刷新的延时,单位为秒,默认 ...

  8. [MyBatis]MyBatis系列:模糊查询的4种实现方式【待完善】

    背景 客户现网遇到的1个子问题. 方案 LIKE + Concat(strA, strB) ... 参考文献 MyBatis系列:模糊查询的4种实现方式

  9. 五月十六号java基础知识点

    1.方法引用就是用双冒号"::"来简化Lambda表达式2.方法引用四种引用方式:1)对象名::实例方法名 //用对象名调用实例方法2)类名::静态方法名 //用类名引用静态方法 ...

  10. 五月八号java基础知识点

    1.对于容器中元素进行访问时,经常需要按照某种次序对容器中的每个元素访问且仅访问 一次,这就是遍历,也称为迭代.2.遍历是指从容器中获得当前元素的后续元素.对元素的遍历有很多种:第一种就是foreac ...