如何停止 vue 的 watch?

7 阅读1分钟

Vue 冷知识:如何停止watch?核心逻辑一文看懂

Vue 开发中,watch 监听数据变化很常用,但有时需要手动停止监听,避免无用回调和内存泄漏。很多人不知道怎么操作,其实核心很简单:利用 watch 的返回值即可。

import { ref, watch } from 'vue'
setup() {
  const num = ref(0)
  const stopWatch = watch(num, (newVal) => console.log(newVal))
  stopWatch() // 直接停止
  return { num }
}

核心结论:this.$watch()(Vue 2)或 watch()(Vue 3)的返回值,就是一个“停止监听函数” ,执行这个函数,就能终止对应的watch监听。

结合 Vue 3 核心源码,看看停止函数的真实实现逻辑:

Vue 3 中,watch 本质是通过创建 effect 实现监听,返回的停止函数,核心是停止对应 effect 的执行,移除监听关联。源码核心逻辑如下:

function watch(source, cb, options = {}) {
  // 1. 创建监听用的 effect(替代 Vue 2 的 Watcher)
  const effect = createEffect(
    () => { /* 监听逻辑:追踪 source 变化 */ },
    () => { /* 变化后执行的回调逻辑 */ },
    options
  )

  // 2. 返回停止监听函数(源码核心)
  function stop() {
    // 停止 effect 执行,移除所有依赖追踪
    effect.stop()
  }

  return stop
}

// effect.stop() 内部核心(精简)
effect.stop = function() {
  if (this.active) {
    // 清除当前 effect 的依赖关联
    cleanupEffect(this)
    // 执行用户可能传入的 onStop 回调(可选)
    if (this.onStop) this.onStop()
    this.active = false
  }
}
  • Vue 3 用 effect 替代了 Vue 2 的 Watcher,停止函数本质是调用 effect.stop(),清除依赖、终止监听。
  • 组件销毁时,Vue 会自动停止所有watch,无需手动操作;临时监听(如弹窗)需手动停止。

总结:停止watch就两步——给watch赋值(拿到停止函数),执行这个变量()。核心逻辑就是利用watch返回的停止函数,删除内部监听实例。