watch 和 watcheffect 均返回可调用的 stop 函数,用于手动停止侦听;需保存返回值并在适当时机(如 onunmounted)调用,多次调用幂等但仅首次生效。

在 Vue 中,watch 返回的停止函数(stop handle)用于手动注销侦听器,防止内存泄漏或避免在组件卸载后仍执行回调。调用它很简单:直接执行该函数即可。
如何获取并调用 stop 函数
使用 watch(尤其是组合式 API 的 watch)时,它会立即返回一个函数,调用它就能停止侦听:
- 在
setup或onMounted等钩子中调用watch,保存其返回值 - 在需要时(如组件卸载前、条件变化时)执行该函数
示例:
import { watch, onUnmounted } from 'vue'
const stopWatch = watch(source, (newVal, oldVal) => {
console.log('值变了', newVal)
})
// 手动停止侦听(比如在某个逻辑分支里)
// stopWatch()
// 推荐:在组件卸载时自动清理
onUnmounted(() => {
stopWatch()
})
watchEffect 也适用相同方式
watchEffect 同样返回可调用的 stop 函数,用法一致:
- 它会自动追踪响应式依赖,无需显式指定 source
- 返回的函数调用后,不再响应后续变化
示例:
import { watchEffect, onUnmounted } from 'vue'
const stop = watchEffect(() => {
console.log('count:', count.value)
})
// 需要时手动停止
// stop()
onUnmounted(stop) // 直接传入,更简洁
注意点:stop 函数只能调用一次
Vue 的 stop 函数是幂等的,多次调用不会报错,但第二次起不再起作用:
- 调用一次后,侦听器彻底失效,后续数据变化不会触发回调
- 不需要担心重复调用导致异常,但也不建议无谓多次调用
- 不要在已 stop 的 watch 上再次尝试读取或重用它
不推荐:依赖 watch 的“自动清理”而不手动 stop
虽然 Vue 3 在组件卸载时会自动清理 watch 和 watchEffect,但在以下场景必须手动调用 stop:
- 侦听器创建在组件外部(如工具函数、全局逻辑中)
- 需提前终止监听(例如用户取消操作、切换 tab、关闭弹窗)
- 同一响应式数据被多个 watch 监听,只停其中某一个
不复杂但容易忽略 —— 记住:拿到返回值,用到就调,不用就 onUnmounted 里清。











