watchEffect是一个立即执行的函数,同时被动地跟踪其依赖项,并在依赖项发生改变时重新运行它。
<script>
import { ref, watchEffect } from 'vue'
export default {
setup() {
const count = ref(0)
watchEffect(() => console.log(count.value))
setTimeout(() => {
count.value++
},1000)
}
}
</script>
控制台会立即打印0,过一秒后打印1。
Stopping the Watcher
当watchEffect在组件的setup()函数或生命周期hooks期间调用时,观察关联到组件的生命周期,并在组件卸载时自动停止。在其它情况下,它返回一个停止的句柄,可以调用它来显示停止watchEffect。
<script>
import { ref, watchEffect } from 'vue'
export default {
setup() {
const count = ref(0)
const stop = watchEffect(() => console.log(count.value))
stop()
setTimeout(() => {
count.value++
), 1000)
}
}
</script>
当执行stop()后打印0,过一秒不会打印1,停止watchEffect。
Side Effect Invalidation
有时被监视的effect函数会执行异步的副作用,需要在失效时进行清理(即在效果完成之前状态发生变化)。effect 函数接收一个onInvalidate可用于注册失效回调的函数。在以下情况下调用此失效回调:
- effect即将重新运行
- 观察者被停止(即当组件被卸载时,如果watchEffect在内部setup()或生命周期钩子中使用)
这点类似于react hook中的useEffect的第一个回调参数,区别是useEffect是通过一个回调参数的返回值来清除副作用的,但是有一点缺点就是当你执行了有关异步的async await函数,这回默认返回promise,浏览器的控制台会提示相关的警告。
watchEffect(onInvalidate => {
const token = performAsyncOperation(id.value)
onInvalidate(() => {
// id has changed or watcher is stopped.
// invalidate previously pending async operation
token.cancel()
})
})