最新版vue3+TypeScript开发入门到实战教程之watch详解

1、watch概述

watch本意是监视、观察。它的功能就是监视数据的变化。数据一旦变化,就会产生两种数据:新数据、旧数据。

如业务场景中,当订单量大多某个数时,就发放优惠卷。watch非常重要,掌握好响应式数据、computed、watch,vue写功能不会有太大问题。

在vue官网明确表达,watch可以监视以下四种数据:

  • ref定义的数据
  • reactive定义的数据
  • 函数返回一个值(getter函数
  • 包含上诉三种值的数组

2、监视ref定义的基本类型数据

  • 创建组件Fish

  • 引入ref、watch

  • 创建响应式数据name、price

  • watch函数监视price变化

  • 当price超过10,watch停止监视price变化

    <template>

    鱼类:{{ name }}

    价格:{{ price }}

    <button @click="addPrice()">增加价格</button> </template> <script setup> import { ref, watch } from 'vue' let name = ref('鲫鱼'); let price = ref(5); function addPrice() { price.value += 1; } let stopWatchPrice = watch(price, (newValue, oldValue) => { console.log(newValue, oldValue); if (newValue > 10) { console.log(stopWatchPrice); stopWatchPrice.stop(); } }) </script>

运行效果事例:

注意watch函数,监视的是price,而不是price.value。当点击按钮,price超过10,虽然数据在增加,但不再监视price。watch函数返回对象,有stop函数,调用此函数,即可解除监视。控制台打印,其结构如下:

复制代码
() => {
    effect2.stop();
    if (scope && scope.active) {
      remove(scope.effects, effect2);
    }
  }

3、监视ref定义的对象类型数据

监视对象类型的数据,与基础类型的数据不同。当对象中的数据变化时,是无法监视到,但当整个数据改变时,是可以监视的。特点如下:

  • 创建组件Fish,引入ref、watch

  • 创建响应式对象fish,let fish = ref({ name: '鲫鱼', price: 5 });

  • 当改变fish.name值时,无法监视fish的变化

  • 当改变fish.price值时,无法监视fish的变化

  • 当改变整条鱼时,能够监视fish变化

    <template>

    鱼类:{{ fish.name }}

    价格:{{ fish.price }}

    <button @click="changeName()">修改鱼类</button> <button @click="changePrice()">修改鱼价</button> <button @click="changeFish()">更换真个鱼</button> </template> <script setup> import { ref, watch } from 'vue' let fish = ref({ name: '鲫鱼', price: 5 });

    function changeName() {
    fish.value.name += '~';
    }
    function changePrice() {
    fish.value.price += 1;
    }
    function changeFish() {
    fish.value = { name: '鲤鱼', price: 10 };
    }
    watch(fish, (newValue, oldValue) => {
    console.log(newValue, oldValue);
    })

运行效果如下:

当修改响应式对象成员变量时,不会引起fish watch函数运行。原因在于watch监视的不是fish.name而是fish。那么如何才能监视fish.namefish.price数据变化呢?

watch函数,它有三个参数

  • 一是监视对象

  • 二是监视回调函数,

  • 三是配置对象参数,如deep等等
    只有在配置对象开启deep即可。

    <template>

    鱼类:{{ fish.name }}

    价格:{{ fish.price }}

    <button @click="changeName()">修改鱼类</button> <button @click="changePrice()">修改鱼价</button> <button @click="changeFish()">更换真个鱼</button> </template> <script setup> import { ref, watch } from 'vue' let fish = ref({ name: '鲫鱼', price: 5 });

    function changeName() {
    fish.value.name += '~';
    }
    function changePrice() {
    fish.value.price += 1;
    }
    function changeFish() {
    fish.value = { name: '鲤鱼', price: 10 };
    }
    watch(fish, (newValue, oldValue) => {
    console.log(newValue, oldValue);
    }, { deep: true })
    </script>

运行效果,仔细观看控制台打印的新数据、旧数据。

  • fish.name改变时,新旧数据一样
  • fish.price改变时,新旧数据一样
  • 当fish整个改变时,新旧数据不一样
    效果如图:

    注意fish.namefish.price,新旧数据是一样的。因为watch是从对象地址取到的数据。

4、watch监视函数返回一个值(getter函数)

它的功能是wath监视响应式对象中一个属性,如监视fish.name,是不允许直接监视,需要写成一个函数的形式。

  • 创建组件Fish,引入reactive, watch

  • 创建响应式对象fish,鱼的名字,鱼的体型:长度、重量

  • 分别监听鱼的名字与体型

  • 点击按钮修改鱼类,鱼的长度、鱼的重量、鱼的体型

    <template>

    鱼类:{{ fish.name }}

    鱼长度:{{ fish.body.long }}

    鱼重量:{{ fish.body.weight }}

    <button @click="changeName()">修改鱼类</button> <button @click="changeFishLong()">修改鱼的长度</button> <button @click="changeFishWeight()">修改鱼的重量</button> <button @click="changeFishbody()">修改鱼的体型</button> </template> <script setup> import { reactive, watch } from 'vue' let fish = reactive({ name: '鲫鱼', body: { long: 1, weight: 24 } });

    function changeName() {
    fish.name += '~';
    }
    function changeFishLong() {
    fish.body.long += 1;
    }
    function changeFishWeight() {
    fish.body.weight += 1;
    }
    function changeFishbody() {
    fish.body = { long: 100, weight: 300 };
    }
    watch(() => { return fish.name }, (newValue, oldValue) => {
    console.log('监听fish.name', newValue, oldValue);
    })
    watch(() => { return fish.body }, (newValue, oldValue) => {
    console.log('监听fish.body', newValue, oldValue);
    })
    </script>

监听响应式对象中的参数,需要写成一个箭头函数,并返回监听参数即可。具体操作,看下图:

当点击按钮,发现只有修改鱼类、修改鱼的体型,才能监听到变化。这是因为watch监听的地址。若想要能够监听到鱼的长度、鱼的重量,需要再watch加入deep参数即可。

复制代码
watch(() => { return fish.body }, (newValue, oldValue) => {
  console.log('监听fish.body', newValue, oldValue);
}, { deep: true })

注意点击按钮修改鱼的长度、修改鱼的重量,新旧数据是一致的。

5、watch监视含有响应式对象数组的数据

watch监视的对象是一个数组,数组内可以是ref定义基本类型数据,也可是对象,可以是函数。

复制代码
watch([() => { return fish.name },() => { return fish.body }], (newValue, oldValue) => {
  console.log('监听素组', newValue, oldValue);
}, { deep: true })

由于使用配置参数deep,操作效果如下:

具体代码

复制代码
<template>
  <h2>鱼类:{{ fish.name }}</h2>
  <h2>鱼长度:{{ fish.body.long }}</h2>
  <h2>鱼重量:{{ fish.body.weight }}</h2>
  <button @click="changeName()">修改鱼类</button>
  <button @click="changeFishLong()">修改鱼的长度</button>
  <button @click="changeFishWeight()">修改鱼的重量</button>
  <button @click="changeFishbody()">修改鱼的体型</button>
</template>
<script setup>
import { reactive, watch } from 'vue'
let fish = reactive({ name: '鲫鱼', body: { long: 1, weight: 24 } });

function changeName() {
  fish.name += '~';
}
function changeFishLong() {
  fish.body.long += 1;
}
function changeFishWeight() {
  fish.body.weight += 1;
}
function changeFishbody() {
  fish.body = { long: 100, weight: 300 };
}
watch([() => { return fish.name },() => { return fish.body }], (newValue, oldValue) => {
  console.log('监听素组', newValue, oldValue);
}, { deep: true })
</script>

6、总结

watch可以监视四种数据,再加上配置函数,内容多且难记。在项目中多练习几次就能熟记。

  • ref定义的数据

  • reactive定义的数据

  • 函数返回一个值(getter函数

  • 包含上诉三种值的数组
    在现实开发中,第一种和第三种情况最常用。尤其第三种情况,加函数,加配置参数deep。属于重中之重。

    watch(() => { return fish.body }, (newValue, oldValue) => {
    console.log('监听fish.body', newValue, oldValue);
    }, { deep: true })

相关推荐
小码哥_常21 小时前
安卓开发秘籍:解锁10大性能优化秘诀
前端
深海鱼在掘金21 小时前
深入浅出 LangChain — 第一章:AI Agent 开发导论
typescript·langchain·agent
深海鱼在掘金21 小时前
深入浅出 LangChain — 导读
typescript·langchain·agent
谁呛我名字1 天前
JavaScript 类型转换与运算规则
javascript
try2find1 天前
打印ascii码报错问题
java·linux·前端
郑州光合科技余经理1 天前
同城O2O海外版二次开发实战:从支付网关到配送算法
开发语言·前端·后端·算法·架构·uni-app·php
冰暮流星1 天前
javascript事件案例-全选框案例
服务器·前端·javascript
Dillon Dong1 天前
【系列主题】Next.js 16 + Turbopack 的暗礁:深入剖析 Tailwind v4 的 CSS 模块解析陷阱
javascript·css·容器·turbopack
Csvn1 天前
前端性能优化实战指南
前端
Moment1 天前
2026 年,AI 全栈时代到了,前端简历别再只写前端技术了 🫠🫠🫠
前端·后端·面试