【composition API】watch

982 阅读1分钟

watch需要观察特定的数据源并在单独的回调中的回调函数中使用副作用。默认情况下它是惰性的,即回调仅在被监视的源发生变化时调用。

与watchEffect相比,watch具备: 懒惰地执行副作用; 更具体地说明什么状态应该watch重新运行; 访问观察状态的先前值和当前值;

Watching a Single Source

观察者数据源可以是一个返回值的getter函数,也可以直接是一个ref:

// watching a getter
const state = reactive({ count: 0 })
watch(
  () => state.count,
  (count, prevCount) => {
    /* ... */
  }
)

// directly watching a ref
const count = ref(0)
watch(count, (count, prevCount) => {
  /* ... */
})

Watching Multiple Sources

观察者还可以使用数组同时观察多个源,但是,如果在同一个函数中同时更改两个监视源,则wacth将只执行一次

<template>
    <div>
        <span>{{ firstName }}</span>
        <span>{{ lastName }}</span>
        <div @click="changeName">change</div>
    </div>
</template>
<script>
import { ref, watch } from 'vue'
export default {
    setup() {
        const firstName = ref('张')
        const lastName = ref('三')
        
        const changeName = () => {
            firstName.value = '李'
            lastName.value = '四'
        }
        
        watch([firstName, lastName], (newVal, prevVal) => {
            console.log(newVal, prevVal) // ['李', '四'] ['张', '三']
        })
        
        return {
            firstName,
            lastName,
            changeName
        }
    }
}
</script>

Watching Reactive Objects

监听深层嵌套对象或数组中的属性,需要把watch的deep选项设置为true

<script>
import { reactive, watch } from 'vue'
export default {
    setup() {
        const state = reactive({
            id: 1,
            attr: {
                name: ''
            }
        })
        
        watch(
            () => state,
            (state, prevState) => {
                console.log('deep', state.attr.name, prevState.attr.name)
            },
            { deep: true }
        )
        
        state.attr.name = '张三'
   }
}
</script>

然而,响应式对象或数组将始终返回对该对象当前值的引用,用于状态的当前值和先前值。要完全观察深层嵌套的对象和数组,可能需要值的深层副本,采用深拷贝方法。