Skip to content

watch 的暂停、恢复、停止

在 Vue 3 中,watch 函数用于监听响应式数据的变化并执行副作用逻辑。然而,有些场景可能需要动态地控制监听行为,例如暂停监听恢复监听彻底停止监听。在本文中,我们将详细介绍如何通过不同方法实现这些功能。

使用 effectScope 控制监听

effectScope介绍

创建一个 effect 作用域,可以捕获其中所创建的响应式副作用 (即计算属性和侦听器),这样捕获到的副作用可以一起处理。

官网地址:https://cn.vuejs.org/api/reactivity-advanced.html#effectscope

示例代码:

以下示例展示了如何使用 effectScope 控制 watch 监听的暂停、恢复和停止:

vue
<script setup>
import { watch } from 'vue';
import { ref, effectScope } from 'vue'

const num = ref(0)

const scope = effectScope()
scope.run(() => {
  watch(num, () => {
    console.log('更新了num的值')
  })
})
function stop() {
  scope.stop()
}
function resume() {
  scope.resume()
}
function pause() {
  scope.pause()
}
</script>

<template>
  <h1>{{ num }}</h1>
  <div>
    <button @click="num++">点我+1</button>
  </div>
  <div>
    <button @click="stop">停止监听</button>
  </div>
  <div>
    <button @click="pause">暂停监听</button>
  </div>
  <div>
    <button @click="resume">恢复监听</button>
  </div>
</template>

跳转到 Vue演练场 查看效果。

注意

  • 暂停和恢复功能依赖于 Vue 3.5+,如果使用较低版本的 Vue,需考虑其他实现方式。
  • stop 方法是 effectScope 的核心功能,无论 Vue 版本如何都可用。

使用返回值控制监听

watch 函数会返回一个停止监听的函数。调用该函数即可停止监听响应式数据的变化。不过,低于 Vue 3.5 的版本无法提供暂停和恢复功能。

示例代码:

以下代码演示了如何通过 watch 的返回值停止监听:

vue
<script setup>
import { watch } from 'vue'

const num = ref(0)

const stop = watch(num, () => {
  console.log('更新了num的值')
})
</script>

<template>
  <h1>{{ num }}</h1>
  <div>
    <button @click="num++">点我+1</button>
  </div>
  <div>
    <button @click="stop">停止监听</button>
  </div>
</template>

局限性

该方法仅支持停止监听,不支持暂停和恢复。

在 vue 3.5.x 版本开始呢,watch 函数返回一个对象,这个对象包含了 stoppauseresume 三个方法,我们可以通过调用这三个方法来暂停、恢复、停止监听。

示例代码:

vue
<script setup>
import { watch } from 'vue';
import { ref, effectScope } from 'vue'

const num = ref(0)

const { stop, resume, pause } = watch(num, () => {
  console.log('更新了num的值')
})
</script>

<template>
  <h1>{{ num }}</h1>
  <div>
    <button @click="num++">点我+1</button>
  </div>
  <div>
    <button @click="stop">停止监听</button>
  </div>
  <div>
    <button @click="pause">暂停监听</button>
  </div>
  <div>
    <button @click="resume">恢复监听</button>
  </div>
</template>

跳转到 Vue演练场 查看效果。

注意

这个特性是在 3.5版本引入的,如果项目使用的 Vue 版本低于 3.5,请升级至最新版本以支持此特性。