你真的会watch监听吗?

543 阅读3分钟

本文是倒过来细过知识点的,之前学习没有彻底搞明白watch监听的知识,现在再来好好的回顾一遍,深入的了解一下watch。

watch的基本用法

watch是vue中的主要是用于监听数据的变化并且在变化的时候执行相应的操作。它的基本用法是:

watch(watchVal,(newVal,oldVal)=>{
    console.log(`值发生了改变,从${oldVal}变为了${newVal}`)
},{option})

从上面代码示例可知watch接收三个参数,

  1. 第一个参数是需要监听的变量,
  2. 第二个参数是一个回调函数,主要执行更新后的相应操作,
  3. 第三个参数是可选择的(根据需要加上第三个参数),他是watch监听器的配置项,主要配置一些深度监听(deep:false),立即监听(immediate:false),回调时机(flush:pre),监听器停止前调用的回调函数((invalidate: () => void) => void)。

后面两个我目前还没用过,到时候再说吧。如果不加入第三个参数的时候,配置的就是默认值,即不会立即监听,深度监听。

监听基本数据类型

image.png

同时监听多个响应式数据也是可以的,第一个参数就是监听多个变量的数组,这个没什么就不做以演示。

监听对象

使用reactive定义一个响应式对象,此时对象是深度响应式的,即使没有设置 {deep:true}, 也是可以监听到内部属性发生了变化,但是我们不能正确的获取到更新前后对象的值,强制深度监听

<template>
  <div>
    <p>我是{{ person.name }}</p>
    <p>我今年{{ person.age }}</p>
    <p>我是{{ person.message.high }}大帅哥</p>
    <button @click="later">一年后</button>
    <button @click="slater">一月后</button>
  </div>
</template>

<script setup>
import {reactive, ref, watch} from 'vue'

const person = reactive({
  name:'小帅',
  age:18,
  message:{    
    high:180
  }
})

const later = () =>{
  person.age++
  person.message.high+=5
}

const slater = () =>{
  person.message.high+=0.5
}

watch(person,(newVal,oldVal)=>{
  console.log(`发生了改变,${oldVal}变为了${newVal}`)
})

</script>

<style lang="scss" scoped>

</style>

image.png

单独监听对象里面的一个变量(基本数据类型)

此时把第一个参数写成函数的形式,就可以监听到里面的变化了

watch(()=>person.message.high,(newVal,oldVal)=>{
  console.log(`发生了改变,${oldVal}变为了${newVal}`)
})

单独监听对象里面的一个变量(引用数据类型)

此时的话就需要配置深度监听了,不然的话监听不到对象里面的引用数据类型。

const person = reactive({
  name:'小帅',
  age:18,
  message:{
    habbits:['吃饭','睡觉','打豆豆'],
    high:180
  }
})
const later = () =>{
  person.message.habbits.push('看书')
}
watch(()=>person.message.habbits,(newVal,oldVal)=>{
  console.log(`发生了改变,${oldVal}  变为了  ${newVal}`)
})

2024-11-26-23-15-24.gif

当我们设置为true后就可以监听到了。为了图方便就不演示了,此时我们还是不能准确拿到改变前的数据。

这是因为: 默认情况下,

  • watch 函数会进行浅层监听,这意味着它只会监听对象的顶层属性变化。
  • 对于复杂数据类型(如对象或数组),浅层监听只会检测到对象或数组的引用变化,而不会深入到对象的内部属性变化,

这样自然不会触发watch的回调

开启 deep 深度监听后,watch 函数会递归地监听对象的所有嵌套属性的变化。

我不想深度监听对象咋办?

使用shallowReactive创建的对象,不会深度监听嵌套属性的变化。

const person = shallowReactive({
  name:'小帅',
  age:18,
  message:{
    habbits:['吃饭','睡觉','打豆豆'],
    high:180
  }
})

具体的演示图与上一张动图一致就不做以展示。

提问式总结

  • watch有三个参数,分别代表xxx?
  • 监听响应式对象,会强制性的深度监听,reactive,Proxy的问题?
  • 怎么监听对象中的基本类型属性?
  • 能不能监听对象中的复杂数据类型属性,怎么监听(深度监听)?
  • 一个对象,但是我不想深度监听怎么做?