Vue 3 中的 Watch、WatchEffect 和 Computed:深入解析与案例分析

引言

在前端开发中,尤其是使用 Vue.js 进行开发时,我们经常需要监听数据的变化以执行相应的操作。Vue 3 提供了三种主要的方法来实现这一目标:watchwatchEffectcomputed。虽然它们都能帮助我们监听数据变化,但各自的适用场景和工作原理有所不同。本文将详细探讨这三者的区别,并通过具体的案例进行说明。

一、Computed 属性

1.1 定义与用途

computed 是 Vue 中用于定义计算属性的方法。它允许你基于其他响应式数据创建一个新的响应式数据。这个新数据会根据其依赖的数据自动更新。

生活中的类比:

想象一下你在超市里购买商品,每个商品都有一个价格标签。当你想要知道购物车里所有商品的总价时,你可以手动计算每件商品的价格乘以其数量,然后加起来得到总价。但是如果你使用了一个智能购物车,它能够自动为你计算总价(只要你知道单价和数量),这就是 computed 的作用------它能帮你自动计算并实时更新结果。

1.2 使用示例

javascript 复制代码
import { ref, computed } from 'vue';

const price = ref(10);
const quantity = ref(5);

const totalPrice = computed(() => {
    return price.value * quantity.value;
});

console.log(totalPrice.value); // 输出: 50

// 修改其中一个变量
price.value = 15;
console.log(totalPrice.value); // 输出: 75 自动更新

二、Watch 监听器

2.1 定义与用途

watch 允许你监听特定的数据源(如响应式引用或 getter 函数的结果),并在数据发生变化时执行回调函数。它可以监听单个源或多个源。

生活中的类比:

假设你现在正在做菜,你需要监控锅里的水是否沸腾。一旦水开始沸腾,你就知道是时候下饺子了。这里,"水是否沸腾"就是你要监听的数据源,而"下饺子"的动作则是监听到变化后执行的操作。

2.2 使用示例

javascript 复制代码
import { ref, watch } from 'vue';

let waterBoiling = ref(false);

watch(waterBoiling, (newValue, oldValue) => {
    if (newValue === true) {
        console.log('Water is boiling, time to add the dumplings!');
    }
});

waterBoiling.value = true; // 触发监听器

2.3 监听多个来源

有时候我们需要同时监听多个数据源的变化:

javascript 复制代码
watch([sourceA, sourceB], ([newSourceA, newSourceB], [oldSourceA, oldSourceB]) => {
    // 处理逻辑
});

三、WatchEffect 响应式效果

3.1 定义与用途

watchEffect 立即运行传入的函数,并响应式地追踪其内部使用的任何 reactive 数据。当这些数据更新时,该函数将再次执行。

生活中的类比:

想象你在厨房里准备晚餐,你需要时刻关注炉子上的火候以及烤箱里的温度。每当任何一个参数发生变化,你都需要相应地调整你的烹饪策略。在这里,watchEffect 就像一个智能助手,它会自动检测这些条件的变化,并即时调整你的行为。

3.2 使用示例

javascript 复制代码
import { ref, watchEffect } from 'vue';

const temperature = ref(180);
const ovenStatus = ref('off');

watchEffect(() => {
    console.log(`Oven status is ${ovenStatus.value}, current temperature is ${temperature.value}`);
});

temperature.value = 200; // 自动触发重新执行
ovenStatus.value = 'on'; // 同样会触发重新执行

四、三者之间的对比

特性 Computed Watch WatchEffect
初始执行 只有当访问时才会执行 立即执行一次 立即执行一次
依赖追踪 自动追踪依赖 需要明确指定依赖 自动追踪依赖
更新时机 当依赖改变时自动更新 当指定的值改变时 当依赖改变时自动更新
返回值 可以返回值 不直接返回值 不直接返回值

五、面试题

问题 1:请简述 computedwatch 的主要区别?

答案:

  • computed 更适合用于需要根据其他状态派生出的新状态,并且这种派生关系是确定性的。
  • watch 更适用于监听某个状态的变化,并在变化发生时执行异步操作或昂贵的计算任务。

问题 2:在什么情况下你会选择使用 watchEffect 而不是 watch

答案: 当你希望立即执行一个副作用并且自动追踪所有被用到的状态作为依赖项时,watchEffect 是更好的选择。它简化了代码结构,因为你不需要显式声明哪些状态是你关心的。

问题 3:如何使用 watch 来监听多个状态的变化?

答案: 可以通过数组的形式传递给 watch,这样就可以同时监听多个状态的变化,并在任一状态发生变化时触发回调函数。


通过以上内容,我们对 watchwatchEffectcomputed 在 Vue 3 中的应用有了较为全面的理解。理解这些工具的不同之处有助于我们在实际项目中做出更合适的选择。无论是构建简单的用户界面还是处理复杂的业务逻辑,正确运用这些功能都可以显著提高我们的开发效率。

相关推荐
荒诞英雄1 小时前
从 17MB Vendor 大包到按需加载:Vite 多入口 Vue 组件库首屏优化实践
vue.js·vite
jsonbro1 小时前
手把手带你实现发布订阅模式
前端·vue.js·设计模式
Cobyte3 小时前
23.Vue Vapor 组件 attrs 的实现
前端·javascript·vue.js
柯克七七6 小时前
给老项目加了 TypeScript,本来只想自己爽,结果全公司代码审查标准被我抬高了
前端·vue.js·typescript
自然 醒8 小时前
前端如何实现在线预览office常见文件功能?
前端·vue.js
肉肉不吃 肉8 小时前
前端调试跨域如何解决
前端·vue.js
卓怡学长8 小时前
w268基于springboot + vue 物流系统
java·数据库·vue.js·spring boot·spring·intellij-idea
迅速的自行车1 天前
从一段模板说起
前端·javascript·vue.js
阿奇__1 天前
uniapp微信小程序图片上传含回显组件(拍照,相册)
前端·javascript·vue.js
前端甜糖1 天前
前端如何实现在线预览office常见文件功能?
前端·vue.js