前端笔记 -- vue3中的watch与watchEffect | 青训营笔记

104 阅读2分钟

这是我参与「第四届青训营 」笔记创作活动的第六天

什么是watch

Vue中的watch又名为侦听属性,它主要用于侦听数据的变化,在数据发生变化的时候执行一些操作。

watch一般有三个参数:

第一个参数:选择要监听的属性。

第二个参数:设置的回调函数。即监听到变化时应该执行的函数 。

第三个参数( 可以不写 ):可以设置deep (深度监听) 其值为true和false。还可以设置immediate (是否以当前值执行回调函数) 其值为true和false

watch的用法

ref

监视一个数据

let sum = ref(2)

watch(sum,(newValue,oldValue)=>{
     
})

监视多个数据

let sum = ref(2)

watch(sum,(newValue,oldValue)=>{
     
})

深度监视ref对象,若不加deep:true则无法监视ref对象

let person =ref({
    name:"xxx"age:18,
    job:{
        salary:"18k"
    }
})

watch(person,(newValue,oldValue)=>{
     
},{deep:true})

reactive

watch监视reactive对象一般会强制开启deep:true

监视一个对象

let person =reactive({
    name:"xxx"age:18
})

watch(person,(newValue,oldValue)=>{

})

监视一个对象中的某个属性

let person =reactive({
    name:"xxx"age:18
})
watch(()=>person.name,(newValue,oldValue)=>{

})

监视多个对象

let person =reactive({
    name:"xxx"age:18
})

watch([()=>person.name,()=>person.age],(newValue,oldValue)=>{

})

监视reactive对象中的一个对象属性(可开启深度监视)

let person =reactive({
    name:"xxx"age:18,
    job:{
        salary:"18k"
    }
})

watch(person.job,(newValue,oldValue)=>{

},{deep:true})

watch的‘坑’

  1. 监视reactive定义的响应式数据时:oldValue无法正确获取、强制开启深度监视(deep配置失效)
  2. 监视reactive定义的响应式数据中的某个属性时:deep配置有效

watchEffect

watchEffect 是 Vue3 中跟踪响应依赖关系的方法之一。本质上,我们可以使用响应性属性编写一个方法,每当它们的任何值更新时,我们的方法就会运行。需要注意的一点是,除了在依赖项更改时运行外,watchEffect 还将在初始化组件时立即运行

示例

每当sumage的值发生变化,watchEffect就会执行回调函数

const sum = ref(2)
const age = ref(18)

watchEffefct(()=>{
    const x1 = sum.value;
    const x2 = age.value;
    
})

使用 onInvalidate() 清除副作用

我们的 watchEffect 方法还有一个 onInvalidate 方法,每当该方法要再次运行或监视程序停止时,该方法就会运行。因此,我们可以像这样停止异步 API 调用。



    watchEffect(onInvalidate => {
      // 异步 API 调用
      const apiCall = someAsyncMethod(props.songID)

      onInvalidate(() => {
        // 取消 API 调用
        apiCall.cancel()
      })
    })


停止观察者

我们还可以手动阻止一个观察者。如果我们想观察一个依赖项,直到它达到某个值,然后停止它,这可能很有用。如果我们在它达到目标值后继续观察,我们只是在浪费资源

我们的 Vue watchEffect 方法返回一个 stop 方法,该方法将停止我们的观察程序。

因此,我们可以简单地将其存储为变量,并在稍后调用它。


    let stopWatcher = watchEffect(() => console.log(props.songID))
    stopWatcher()