最新版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 })

相关推荐
MinterFusion几秒前
HTML DOM元素的定位问题
前端·css·html
落魄江湖行13 分钟前
入门篇六 Nuxt4错误处理:给应用装个安全气囊
前端·typescript·nuxt4
薛定猫AI17 分钟前
【技术干货】用 design.md 驯服 AI 生成前端:从 Awesome Design 到工程化落地实践
前端·人工智能
kyriewen20 分钟前
你的JS代码总在半夜崩溃?TypeScript来“上保险”了
前端·javascript·typescript
iReachers38 分钟前
HTML打包EXE配置管理教程:多项目打包设置一键保存、加载与切换
java·前端·javascript
武藤一雄41 分钟前
WPF中ViewModel之间的5种通讯方式
开发语言·前端·microsoft·c#·wpf
霍理迪1 小时前
Vue路由——route
前端
whuhewei1 小时前
js事件循环
前端·javascript
TheRouter1 小时前
构建一个支持多模型的 AI 聊天应用:React + TheRouter API 全栈教程
前端·人工智能·react.js
xiaofan11061 小时前
Pretext:无 DOM 的多行文本测量与排版库
前端·javascript