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

相关推荐
okra-2 小时前
Axure RP 10 进阶指南:从全局变量到JavaScript语法,打造高效原型设计!
javascript·axure·photoshop
默默学前端2 小时前
ES6模板语法与字符串处理详解
前端·ecmascript·es6
lxh01132 小时前
记忆函数 II 题解
前端·javascript
我不吃饼干2 小时前
TypeScript 类型体操练习笔记(三)
前端·typescript
华仔啊2 小时前
除了防抖和节流,还有哪些 JS 性能优化手段?
前端·javascript·vue.js
CHU7290353 小时前
随时随地学新知——线上网课教学小程序前端功能详解
前端·小程序
清粥油条可乐炸鸡3 小时前
motion入门教程
前端·css·react.js
这是个栗子3 小时前
【Vue3项目】电商前台项目(四)
前端·vue.js·pinia·表单校验·面包屑导航
前端Hardy3 小时前
Electrobun 正式登场:仅 12MB,JS 桌面开发迎来轻量化新方案!
前端·javascript·electron