【composition API】watchEffect

266 阅读1分钟

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()
  })
})