Vue3--Watch、Watcheffect、Computed的使用和区别

Vue3–Watch、Watcheffect、Computed的使用和区别

一、watch

1.功能

watch 用于监听响应式数据的变化,并在数据变化时执行特定的回调函数。适合在响应式数据变化时执行异步操作或复杂逻辑。

2.主要特点

  1. 指定数据监听:可以精确地监听一个或多个响应式数据。
  2. 回调函数:数据变化时调用指定的回调函数,并传入新值和旧值。
  3. 配置项:支持 immediate(是否立即执行回调)和 deep(是否深度监听)配置。

3.典型应用场景

  • 需要执行异步操作(如 API 请求)。
  • 需要执行复杂的副作用操作。
  • 需要监听深层次的对象变化。
import { ref, watch } from 'vue';
const count = ref(0);
watch(count, (newValue, oldValue) => {console.log(`依赖值改变${oldValue} -- ${newValue}`);
}, { immediate: true, deep: false });

4.参数介绍

  • 第一个参数:需要监听的响应式数据或 getter 函数。
  • 第二个参数:回调函数,接受新值和旧值作为参数。
  • 第三个参数(可选):配置项,包括 immediatedeep

5.基本使用示例(父子组件结合ElementUI)

父组件

<template><div><!-- 使用 ElementUI 的 el-input 组件输入内容 --><el-input v-model="parentInput" placeholder="Enter something"></el-input><!-- 将输入内容传递给子组件 --><ChildComponent :inputValue="parentInput" /></div>
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
// 创建一个响应式变量 parentInput,用于存储输入内容
const parentInput = ref('');
</script>

子组件

<template><div><!-- 显示父组件传递的输入内容 --><p>父组件输入: {{ inputValue }}</p></div>
</template>
<script setup>
import { watch, toRefs } from 'vue';
// 定义 props 接收父组件传递的数据
const props = defineProps({inputValue: String,
});
// 解构 props
const { inputValue } = toRefs(props);
// 监听 inputValue 的变化,并在变化时执行回调
watch(inputValue, (newValue) => {console.log(`父组件输入改变: ${newValue}`);
});
</script>

6.常见用法

1. 监听单个响应式数据
import { ref, watch } from 'vue';
const count = ref(0);
watch(count, (newValue, oldValue) => {console.log(`count值改变 ${oldValue} -- ${newValue}`);
});
2. 监听多个响应式数据
import { ref, watch } from 'vue';const count1 = ref(0);
const count2 = ref(0);watch([count1, count2], ([newCount1, newCount2], [oldCount1, oldCount2]) => {console.log(`count1值改变 ${oldCount1} -- ${newCount1}`);console.log(`count2值改变 ${oldCount2} -- ${newCount2}`);
});
3. 深度监听对象{ deep: true }
import { ref, watch } from 'vue';
const person = ref({ name: 'John', age: 30 });
watch(person, (newPerson, oldPerson) => {console.log(`Person改变 ${oldPerson.name} -- ${newPerson.name}`);
}, { deep: true });
4. 立即执行回调{ immediate: true }
import { ref, watch } from 'vue';
const count = ref(0);
watch(count, (newValue, oldValue) => {console.log(`count值改变 ${oldValue} -- ${newValue}`);
}, { immediate: true });
5. 监听 getter 函数
import { ref, watch } from 'vue';
const count = ref(0);
// 使用 watch 监听一个 getter 函数
watch(// 第一个参数是一个 getter 函数,该函数返回我们要监听的计算值() => count.value + 1,// 第二个参数是回调函数,当 getter 函数的返回值发生变化时,该回调函数会被调用(newValue, oldValue) => {// 打印旧值和新值console.log(`Computed值改变 ${oldValue} -- ${newValue}`);}
);

二、watchEffect

1.功能

watchEffect 用于自动运行一个副作用函数,并追踪其依赖。任何依赖变化时都会重新运行该函数。适合用来执行副作用,但不需要明确指定依赖。

2.主要特点

  1. 自动依赖追踪:自动追踪副作用函数中的响应式数据依赖。
  2. 立即执行:函数会立即执行一次,并在依赖变化时重新执行。
  3. 简洁性:不需要手动指定依赖,代码更简洁。

3.典型应用场景

  • 需要自动运行副作用函数,并自动管理依赖。
  • 界面更新或 DOM 操作。
import { ref, watchEffect } from 'vue';
const count = ref(0);
watchEffect(() => {console.log(`count: ${count.value}`);
}, { flush: 'pre' });

4.参数介绍

  • 第一个参数:副作用函数。
  • 第二个参数(可选):配置项,包括 flush

watchEffectflush 选项用于控制副作用函数的触发时机。flush 选项有三种可能的值:

  1. pre:在组件更新前触发(这是默认值)。
  2. post:在组件更新后触发。
  3. sync:同步地触发。

flush: ‘pre’

默认情况下,watchEffect 会在组件更新之前运行副作用函数。这意味着当响应式数据变化时,副作用会在 DOM 更新前执行。

flush: ‘post’

flush 设置为 'post' 可以在组件更新后触发副作用函数。这对于那些需要访问更新后的 DOM 元素的副作用来说很有用。

flush: ‘sync’

flush 设置为 'sync' 可以使副作用同步触发,而不是等到下一个微任务队列。这意味着副作用会立即在响应式数据变化时执行。

import { ref, watchEffect } from 'vue';const count = ref(0);// 默认 flush: 'pre'
watchEffect(() => {console.log(`count (pre): ${count.value}`);
});// flush: 'post'
watchEffect(() => {console.log(`count (post): ${count.value}`);
}, { flush: 'post' });// flush: 'sync'
watchEffect(() => {console.log(`count (sync): ${count.value}`);
}, { flush: 'sync' });count.value++;

三个 watchEffect 会在不同的时机记录 count 的值:

  1. flush: 'pre' 会在 DOM 更新前执行。
  2. flush: 'post' 会在 DOM 更新后执行。
  3. flush: 'sync' 会同步执行。

5.基本使用示例(父子组件结合ElementUI)

父组件

<template><div><!-- 使用 ElementUI 的 el-slider 组件输入数值 --><el-slider v-model="sliderValue"></el-slider><!-- 将滑动条的值传递给子组件 --><ChildComponent :sliderValue="sliderValue" /></div>
</template><script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
// 创建一个响应式变量 sliderValue,用于存储滑动条的值
const sliderValue = ref(50);
</script>

子组件

<template><div><!-- 显示父组件传递的滑动条的值 --><p>Slider value: {{ sliderValue }}</p></div>
</template>
<script setup>
import { watchEffect, toRefs } from 'vue';
// 定义 props 接收父组件传递的数据
const props = defineProps({sliderValue: Number,
});
// 解构 props
const { sliderValue } = toRefs(props);
// 监听 sliderValue 的变化,并在变化时执行副作用函数
watchEffect(() => {console.log(`Slider: ${sliderValue.value}`);
});
</script>

6.常见用法

1. 基本用法
import { ref, watchEffect } from 'vue';
const count = ref(0);
watchEffect(() => {console.log(`count: ${count.value}`);
});
2. 取消副作用
import { ref, watchEffect } from 'vue';
const count = ref(0);
const stop = watchEffect(() => {console.log(`count: ${count.value}`);
});
// 停止副作用
stop();
3. 延迟执行{ flush: ‘post’ }
import { ref, watchEffect } from 'vue';
const count = ref(0);
watchEffect(() => {console.log(`count: ${count.value}`);
}, { flush: 'post' });
4. 自定义调度
import { ref, watchEffect } from 'vue';
const count = ref(0);
// 使用 watchEffect 自动追踪副作用
watchEffect(() => {// 这个函数在 count 发生变化时会被调用console.log(`count: ${count.value}`);},{// 配置项:onTrack 和 onTrigger 是调试钩子// onTrack 会在副作用追踪依赖时调用onTrack(e) {console.log('tracked', e);},// onTrigger 会在依赖变化导致副作用重新执行时调用onTrigger(e) {console.log('triggered', e);}}
);

三、computed

1.功能

computed 用于声明计算属性,计算属性会根据其依赖的响应式数据自动更新,并且具有缓存特性。适合计算派生状态或数据。

2.主要特点

  1. 依赖管理:计算属性根据依赖的响应式数据自动更新。
  2. 缓存:只有当依赖的数据变化时,计算属性才会重新计算。
  3. 简洁性:声明式地定义派生数据,代码简洁且易于维护。

3.典型应用场景

  • 需要根据其他响应式数据派生出新的数据。
  • 需要高效的、缓存的计算属性。
import { ref, computed } from 'vue';
const count = ref(0);
const doubleCount = computed(() => count.value * 2);

4.参数介绍

  • 第一个参数:getter 函数,返回计算属性的值。
  • 第二个参数(可选):setter 函数,用于设置计算属性的值(可写计算属性)。

5.基本使用示例(父子组件结合ElementUI)

父组件

<template><div><!-- 使用 ElementUI 的 el-input 组件输入数值 --><el-input v-model="inputValue" placeholder="Enter a number"></el-input><!-- 将输入的数值传递给子组件 --><ChildComponent :number="inputValue" /></div>
</template><script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
// 创建一个响应式变量 inputValue,用于存储输入的数值
const inputValue = ref(0);
</script>

子组件

<template><div><!-- 显示父组件传递的数值的平方 --><p>Squared value: {{ squaredNumber }}</p></div>
</template><script setup>
import { computed, toRefs } from 'vue';
// 定义 props 接收父组件传递的数据
const props = defineProps({number: Number,
});
// 解构 props
const { number } = toRefs(props);
// 创建一个计算属性 squaredNumber,计算 number 的平方
const squaredNumber = computed(() => number.value * number.value);
</script>

6.常见用法

1. 基本用法
import { ref, computed } from 'vue';
const count = ref(0);
const doubleCount = computed(() => count.value * 2);
2. 可写计算属性 (get set)
import { ref, computed } from 'vue';
const firstName = ref('John');
const lastName = ref('Doe');
const fullName = computed({get: () => `${firstName.value} ${lastName.value}`,set: (newValue) => {const names = newValue.split(' ');firstName.value = names[0];lastName.value = names[1];},
});
3. 依赖其他计算属性
import { ref, computed } from 'vue';
const count = ref(0);
const doubleCount = computed(() => count.value * 2);
const tripleCount = computed(() => doubleCount.value * 1.5);
4. 使用在模板中
<template><div>{{ doubleCount }}</div>
</template>
<script setup>
import { ref, computed } from 'vue';
const count = ref(0);
const doubleCount = computed(() => count.value * 2);
</script>
5. 配合 watch 使用
import { ref, computed, watch } from 'vue';
const count = ref(0);
const doubleCount = computed(() => count.value * 2);
watch(doubleCount, (newValue) => {console.log(`doubleCount: ${newValue}`);
});
6. 配合 watchEffect 使用
import { ref, computed, watchEffect } from 'vue';
const count = ref(0);
const doubleCount = computed(() => count.value * 2);
watchEffect(() => {console.log(`doubleCount: ${doubleCount.value}`);
});

四、总结与区别

watch 的多种用法

  • 监听单个响应式数据。
  • 监听多个响应式数据。
  • 深度监听对象。{ deep: true }
  • 立即执行回调。{ immediate: true }
  • 监听 getter 函数。

watchEffect 的多种用法

  • 基本用法。
  • 取消副作用。
  • 延迟执行。{ flush: ‘post’ }
  • 自定义调度。

computed 的多种用法

  • 基本用法。
  • 可写计算属性。 (get set)
  • 依赖其他计算属性。
  • 使用在模板中。
  • 配合 watch 使用。
  • 配合 watchEffect 使用。

区别

特性watchwatchEffectcomputed
功能监听响应式数据变化并执行回调自动运行副作用函数并追踪依赖声明计算属性,根据依赖自动更新并缓存
依赖管理手动指定自动追踪自动管理
缓存
适用场景异步操作、复杂副作用、深度监听界面更新、副作用函数派生状态、数据计算
优点精确控制、支持异步操作自动依赖追踪、代码简洁声明式、自动更新、缓存
缺点需要手动指定依赖、代码相对复杂每次依赖变化时都会重新执行副作用函数需要在创建时指定依赖,无法动态改变计算逻辑

Watch、Watcheffect、Computed三种方法各有优劣,选择使用哪种方法主要取决于具体的应用场景和需求。watch 适合复杂的副作用操作,watchEffect 适合简单的自动副作用管理,而 computed 适合声明式的派生状态计算。

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

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

相关文章

python:如何防止隔壁老王破你的WIFI?

Python 与网络安全&#xff1a;最佳拍档 Python 凭借其简洁的语法和丰富的库支持&#xff0c;成为进行网络安全测试和加固的理想选择。下面&#xff0c;我们将深入几个实用场景&#xff0c;看看 Python 如何帮助我们成为自家网络安全的守护者。 1. 网络监控&#xff1a;Scapy…

Elasticsearch实战教程:如何使用集群索引数据来进行统计多个数据?

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 引入 Elasticsearch聚合查询是一种强大的工具&#xff0c;允许我们对索引中的数据进行复杂的统计分析和计算。本文将详细解释一…

CFS三层内网渗透——外网打点(一)

目录 外网打点 先爆破一下看看有没有啥可进攻路径 尝试那个可疑的路径发现是thinkphp这个框架&#xff0c;同时也知道了版本&#xff0c;那就nday打吧 写入php ​编辑写入php成功&#xff0c;简简单单nday拿下​编辑 蚁剑rce尝试链接 打点成功 外网打点 先爆破一下看看有…

(自适应手机端)保健品健康产品网站模板下载

(自适应手机端)保健品健康产品网站模板下载PbootCMS内核开发的网站模板&#xff0c;该模板适用于装修公司网站、装潢公司网站等企业&#xff0c;当然其他行业也可以做&#xff0c;只需要把文字图片换成其他行业的即可&#xff1b;自适应手机端&#xff0c;同一个后台&#xff0…

己内酰胺纯化除杂的最佳工艺

己内酰胺纯化除杂的最佳工艺包括结晶法、离子交换树脂法、精馏法和萃取法等&#xff0c;每种方法都有其特定的应用场景和优缺点。以下是对这些方法的详细介绍&#xff1a; 最佳工艺介绍 ● 结晶法&#xff1a;通过调节pH值&#xff0c;使己内酰胺在特定条件下结晶&#xff0…

数字流的秩

题目链接 数字流的秩 题目描述 注意点 x < 50000 解答思路 可以使用二叉搜索树存储出现的次数以及数字的出现次数&#xff0c;方便后续统计数字x的秩关键在于构建树的过程&#xff0c;如果树中已经有值为x的节点&#xff0c;需要将该节点对应的数字出现次数加1&#xf…

2025深圳国际消费电子展览会

2025深圳国际消费电子展览会 时间&#xff1a;2025年06月25-27日 地点&#xff1a;深圳国际会展中心(新馆) 详询主办方陆先生 I38&#xff08;前三位&#xff09; I82I&#xff08;中间四位&#xff09; 9I72&#xff08;后面四位&#xff09; 展会介绍&#xff1a; 20…

JAVA API营业执照识别、企业工商信息查询

现如今&#xff0c;随着互联网技术的不断成熟与智能应用的不断普及&#xff0c;人们对于营业执照识别技术的需求越来越大。像工商、税务、银行、网上注册等一些应用场景在进行经营活动和业务中&#xff0c;都需要对营业执照的信息进行采集和录入&#xff0c;无论是个人业务还是…

父子情深短视频:成都柏煜文化传媒有限公司

成都柏煜文化传媒有限公司 &#xff0c;镜头下的温馨时光 在这个快节奏、高压力的时代&#xff0c;人们往往在忙碌中忽略了身边最珍贵的情感纽带。然而&#xff0c;在社交媒体的浪潮中&#xff0c;有一种短视频以其独特的魅力&#xff0c;悄然温暖了无数人的心房——那就是父…

从零开始开发跑腿配送系统:技术选型与架构设计

开发一个跑腿配送系统涉及多个技术栈和模块&#xff0c;从前端到后端&#xff0c;再到数据库和实时通信&#xff0c;每一个环节都至关重要。本文将详细介绍从零开始开发跑腿配送系统的技术选型与架构设计&#xff0c;并提供部分代码示例以帮助理解。 一、技术选型 前端技术&am…

Linux/Ubuntu访问局域网共享文件夹

文件夹中找到“Other Location”&#xff0c;输入“smb:IP地址/共享文件夹名称”&#xff0c;然后点击connect后者直接回车即可&#xff01; End&#xff01;

五.核心动画 - 图层的变换(平移,缩放,旋转,3D变化)

引言 在上一篇博客中&#xff0c;我们研究了一些视觉效果&#xff0c;在本篇博客中我们将要来讨论一下图层的旋转&#xff0c;平移&#xff0c;缩放&#xff0c;以及可以将扁平物体转换成三维空间对象的CATransform3D。 图层变换 图层的仿射变换 在视图中有一个transform属…

【机器学习】分类算法-KNN算法实践

一、前言 前面的一篇文章介绍了KNN算法的基本思想&#xff0c;接下来我们就根据B站UP主【abilityjh】老师的节奏&#xff0c;做一个关于KNN算法运用于“约会网站配对”的算法实现。当然&#xff0c;这个实践的代码是一样的&#xff0c;但是理解的话&#xff0c;我是用自己的话来…

代码技巧专题 -- 使用策略模式编写HandleService

一.前言 最近项目有实习的同事加入&#xff0c;很多实习同事反映&#xff0c;看不懂项目中的一些使用了设计模式的代码&#xff0c;比如HandleService&#xff0c;Chains&#xff0c;Listener等。本篇就介绍一下策略模式在项目中的使用&#xff0c;也就是我们常在项目中看到的X…

Lemo 的项目管理类博文导航

&#x1f447;&#x1f447;&#x1f447;&#x1f447;&#x1f447;&#x1f447; 升级大脑&#xff01;构建你的个人知识管理系统的黄金法则 &#x1f447;&#x1f447;&#x1f447;&#x1f447;&#x1f447;&#x1f447; 如何优雅做好项目管理&#xff1f; 软件质量大…

抖音微短剧小程序入驻指南

一、抖音微短剧小程序类目和准入要求是什么&#xff1f; 可以明确的告诉你抖音微短剧小程序入驻是需要报白的&#xff0c;属于定邀类目&#xff0c;官方准入要求如下&#xff1a; 类目要求&#xff1a;文娱-微短剧 定向准入&#xff0c;填写“【微短剧】类目定向邀约申请表”…

【MindSpore学习打卡】应用实践-计算机视觉-SSD目标检测:从理论到实现

在计算机视觉领域&#xff0c;目标检测是一个至关重要的任务。它不仅要求识别图像中的目标物体&#xff0c;还需要精确定位这些物体的位置。近年来&#xff0c;随着深度学习技术的飞速发展&#xff0c;各种高效的目标检测算法层出不穷。SSD&#xff08;Single Shot MultiBox De…

​埃文科技受邀出席2024 “数据要素×”生态大会​

2024“数据要素”生态大会&#xff08;以下简称“大会”&#xff09;于2024年6月30日在河南省郑州市举办&#xff0c;大会主题为“加快数据要素化进程 推动新质生产力发展”。 本次大会旨在搭建高水平交流合作平台、分享前沿观点、展示先进技术、交流实践经验&#xff0c;共同探…

IPSS模块怎么安装到VOS服务器的,到底有没有效果,是不是能大幅度提升VOS3000安全性呢

由于VOS的普及性&#xff0c;不得不承认VOS确实是非常优秀的软交换&#xff0c;但是很多客户在使用过程中都会遇到各种安全问题&#xff0c;比如话费被盗用了&#xff0c;历史话单一堆的非法呼叫话单&#xff0c;严重的影响到了话务安全&#xff0c;并不是那点话费的事了&#…

彻底搞懂Kafka生产消费流程,这篇文章就够了!

Hey, 小伙伴们!今天小米给大家带来一篇关于Kafka生产消费基本流程的揭秘,内容超干货!让我们一起揭开Kafka神秘的面纱,探索它的工作原理吧! Producer创建及其内部结构 当我们创建一个Kafka Producer时,Kafka会为我们创建一个叫做Sender的线程,并将其设置为守护线程(Da…