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.mfbz.cn/a/774494.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

缓存与数据库数据一致性问题

在用了redis缓存的系统中&#xff0c;正常情况下&#xff0c;一个读操作会先查缓存&#xff0c;如果在缓存中查到了&#xff0c;则直接返回&#xff0c;如果缓存中没有&#xff0c;则会查数据库&#xff0c;再将查到的数据写到redis中&#xff0c;然后返回。如下图&#xff1a;…

PDI-kettle工具连接本地虚拟机Ubuntu上的数据库

PDI 配置ubuntu数据库配置Kettle工具 PDI版本&#xff1a;9.4 Ubuntu2204&#xff1a;10.11.8-MariaDB-0ubuntu0.24.04.1 Ubuntu 24.04 配置ubuntu数据库 安装 apt install -y mariadb-server配置监听地址 cat > /etc/mysql/mariadb.conf.d/99-kettle.cnf << EOF …

国衍科技——梅雨季节文物保护专家

尊敬的文物保护者们 随着梅雨季节的脚步渐近&#xff0c;湿润的空气和连绵的雨水不仅为我们的生活带来了不便&#xff0c;更为文物保护工作带来了严峻的挑战。在这个季节&#xff0c;文物发霉的风险急剧上升&#xff0c;每一件珍贵的文化遗产都面临着被时间侵蚀的威胁。然而&am…

玩转内网穿透详细教程,收藏这一篇就够了

小朋友&#xff0c;你是否有过以下这些烦恼&#xff1f; 当你在外地&#xff0c;苦于无法拿到存储在家里的资料&#xff1b; 当你在玩游戏的时候&#xff0c;苦于无法和朋友直接联机&#xff1b; 当你在家里&#xff0c;苦于无法通过自己的电脑连上公司电脑远程办公&#xf…

WPF在.NET9中的重大更新:Windows 11 主题

在2023年的2月20日&#xff0c;在WPF的讨论区&#xff0c;WPF团队对路线的优先级发起了一次讨论。 对三个事项发起了投票。 第一个是Windows 11 主题 第二个是更新的控件 第三个是可空性注释 最终Windows 11 主题得票最高&#xff0c;WPF团队2023-2024的工作优先级就是Windows…

VUE3使用antd引入百度地图 实现位置查询,获取地址经纬度

实现效果: 1.index.html 中先引入下 <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=自己申请的key"></script> 申请密钥key地址:登录百度账号 注册登录后创建应用,根据自己需求选择 2.新建bmp.js文件…

期权学习必看圣书:《3小时快学期权》要在哪里看?

今天带你了解期权学习必看圣书&#xff1a;《3小时快学期权》要在哪里看&#xff1f;《3小时快学期权》是一本关于股票期权基础知识的书籍。 它旨在通过简明、易懂的语言和实用的案例&#xff0c;让读者在短时间内掌握股票期权的基本概念、操作方法和投资策略。通过这本书&…

Hyper-V克隆虚拟机教程分享!

方法1. 使用导出导入功能克隆Hyper-V虚拟机 导出和导入是Hyper-V服务器备份和克隆的一种比较有效的方法。使用此功能&#xff0c;您可以创建Hyper-V虚拟机模板&#xff0c;其中包括软件、VM CPU、RAM和其他设备的配置&#xff0c;这有助于在Hyper-V中快速部署多个虚拟机。 在…

数字信号处理实验二(模拟信号采样与重构及频谱分析FFT)

模拟信号采样与重构及频谱分析FFT&#xff08;2学时&#xff09; 要求&#xff1a; 对一模拟信号进行采样&#xff1b;对该采样信号进行重构&#xff1b;分析它们的频谱特征。目的&#xff1a; 熟悉MATLAB命令和编辑、运行、调试环境&#xff1b;掌握采样定理及对信号的频谱分析…

无线领夹麦克风怎么挑选,无线领夹麦克风哪个品牌音质最好详解!

在数字化内容创作的浪潮中&#xff0c;无线领夹麦克风凭借其轻便的设计和卓越的录音性能&#xff0c;成为了许多创作者不可或缺的音频帮手。这种类型的麦克风能够轻松附着在衣物上&#xff0c;使得创作者在进行直播或录制视频时能够自由移动&#xff0c;而不受传统麦克风线缆的…

STM32智能家居安防系统教程

目录 引言环境准备智能家居安防系统基础代码实现&#xff1a;实现智能家居安防系统 4.1 数据采集模块 4.2 数据处理与分析 4.3 控制系统实现 4.4 用户界面与数据可视化应用场景&#xff1a;安防管理与优化问题解决方案与优化收尾与总结 1. 引言 智能家居安防系统利用STM32嵌…

前端从业者的历史难题Vue和React的抉择:难度不亚于丈母娘和媳妇

**前端从业者的历史难题&#xff1a;Vue和React的抉择——难度不亚于丈母娘和媳妇** Vue和React这两个框架无疑是当下最为流行的两个选择。它们各自拥有独特的优势和特点&#xff0c;吸引了大量的前端从业者。然而&#xff0c;对于许多从业者来说&#xff0c;如何在Vue和React…

D. Beauty of the mountains(cf955)

分析&#xff1a;有一个n*m的数组a&#xff0c;对应n*m的数组b&#xff0c;想让b0的下标的a的数组之和等于b1的下标的a的数组之和&#xff0c;你可以进行k*k的范围所有数字全部加任意数。 求出子矩阵里0和1的差值&#xff1b; #include<bits/stdc.h> using namespace st…

Android 四大组件

1. Activity 应用程序中&#xff0c;一个Activity通常是一个单独的屏幕&#xff0c;它上面可以显示一些控件&#xff0c;也可以监听并对用户的事件做出响应。 Activity之间通过Intent进行通信&#xff0c;在Intent 的描述结构中&#xff0c;有两个最重要的部分&#xff1a;动…

电子行业MES系统解决方案

工业4.0时代的工业自动化&#xff0c;将在原有自动化技术和架构下&#xff0c;实现集中式控制向分散式增强型控制的基本模式转变&#xff0c;让设备从传感器到因特网的通讯能够无缝对接&#xff0c;从而建立一个高度灵活的、个性化和数字化、融合了产品与服务的生产模式。在这种…

springboot城市菜园共享系统-计算机毕业设计源码00524

目 录 摘要 1 绪论 1.1 研究背景与意义 1.2 国内外研究现状和发展趋势 1.3论文结构与章节安排 2 城市菜园共享系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据增加流程 2.2.2 数据修改流程 2.2.3 数据删除流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.…

Keepalived+HAProxy 集群及虚IP切换实践

1、软件介绍 ①Keepalived keepalive是一个用c语言编写的路由软件&#xff0c;这个项目的主要目标是为Linux系统和基于Linux的基础设施提供简单而健壮的负载平衡和高可用性设施。负载均衡框架依赖于众所周知且广泛使用的Linux Virtual Server (IPVS)内核模块提供第4层负载均衡…

Renderless 思想正在影响前端开发

本文由前端小伙伴方长_beezen 原创。欢迎大家踊跃投稿。 原文链接&#xff1a;https://juejin.cn/post/7385752495535472655 前言 截止到 2024 年&#xff0c;跨端应用开发所需要考虑的兼容性&#xff0c;已经涵盖了框架、平台和设备类型等多个方面&#xff0c;例如&#xff1…

ES集成到ambari中出现的常见问题归总

1.elasticesearch用户名组的问题 KeyError: uelasticsearch Error: Error: Unable to run the custom hook script [/usr/bin/python, /var/lib/ambari-agent/cache/stack-hooks/before-ANY/scripts/hook.py, ANY, /var/lib/ambari-agent/data/command-102.json, /var/lib/amb…

Runway Gen-3 实测,这就是 AI 视频生成的 No.1!视频高清化EvTexture 安装配置使用!

Runway Gen-3 实测,这就是 AI 视频生成的 No.1!视频高清化EvTexture 安装配置使用! 由于 Runway 作为一个具体的工具或平台,其详细信息在搜索结果中没有提供,我将基于假设 Runway 是一个支持人工智能和机器学习模型的创意工具,提供一个关于使用技巧和类似开源项目的文稿总…