_
2024/4/3 00:14:00542

watch侦听器

在选项式API中,我们学过watch侦听器,在组合式API中同样可以使用侦听器,只是语法上有了一些变化。

我们先构建一个基础场景,就好比我们声明了一个响应式变量 message 默认为hello world 然后渲染在一个div里面,当点击这个div时我们来修改messgae变量这个值。

<template>
  <div @click="changeMessage">{{ message }}</div>
</template>

<script>
import {ref} from "vue"
export default{
  setup(){
    const message = ref("hello world!")

    const changeMessage = ()=>{
      message.value="hello vue"
    }

    return{
      message,
      changeMessage
    }
  }
}
</script>

我们一起来看一下组合式API中怎么来使用watch侦听器,在组合式API中watch是以一个函数API的方式来使用的。

首先从vue中引入获取watch API,然后到 setup调用此API,第一个参数表示需要监听的响应式数据,第二个参数是一个回调函数当监听的数据发生变化时,会执行此函数,它会传递两个参数(newValue,oldValue)

根据上面的基础代码,我们来监听一下mseaage这个响应式变量,当点击div时message数据发生变化会打印出新值和旧值。

import {reactive,watch} from "vue"
export default{
  setup(){
    const message = ref("hello world!")

    const changeMessage = ()=>{
      message.value="hello vue"
    }

    watch(message,(newValue,oldValue)=>{
      console.log("messgae 发生变化 新值:"+newValue+" 旧值:"+oldValue)
      //打印结果:messgae 发生变化 新值:hello vue 旧值:hello world!  
    })

    return{
      message,
      changeMessage
    }
  }
}

使用watch侦听reactive对象

用watch监听,reactive对象,当对象被覆盖或里面的属性发生变化时watch也能监听到(深层侦听器)。

import {reactive,watch} from "vue"
export default{
  setup(){
    const userinfo = reactive({
      name:"小朱"
    })

    const changeMessage = ()=>{
      userinfo.name="小张"
    }

    watch(userinfo,(newValue,oldValue)=>{
      console.log(newValue)
      console.log(oldValue)
    })

    return{
      userinfo,
      changeMessage
    }
  }
}

单独只想侦听reactive中某个属性时,比如侦听user.name,直接写是没有效果,我们需要使用箭头函数包装getter 函数。

watch(()=>userinfo.name,(newValue,oldValue)=>{
  console.log(newValue)
  console.log(oldValue)
})

侦听reactive中的嵌套对象时,只有当整个对象被重新覆盖才会触发。

const userinfo = reactive({
   name:"小朱",
   profile:{
     class:"六年级"
   }
})

const changeMessage = ()=>{
   //覆盖整个对象 会触发watch侦听
   userinfo.profile={class:"七年级"}
   
   //只是修改嵌套对象的某个属性值是不会触发watch侦听
   userinfo.profile.class="七年级" 

}

watch(()=>userinfo.profile,(newValue,oldValue)=>{
  console.log(newValue)
  console.log(oldValue)
})

嵌套对象深层侦听,只是修改嵌套对象的某个属性值是不会触发watch侦听,解决这个问题可以在第三个参数重提供{deep:true}选项,强制转成深层侦听器。

watch(()=>userinfo.profile,(newValue,oldValue)=>{
  console.log(newValue)
  console.log(oldValue)
},{deep:true})

//谨慎使用
//深度侦听需要遍历被侦听对象中的所有嵌套的属性,当用于大型数据结构时,开销很大。
//因此请只在必要时才使用它,并且要留意性能。

侦听多个数据源

用数组组合可以实现同时侦听多个数据,回调函数也将会使用数组组合返回数据。

 watch(
      [()=>userinfo.name,message],
      ([newName,neMessage],[oldName,oldMessage])=>{
        console.log([newName,neMessage],[oldName,oldMessage])
      }
    )