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