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返回的停止函数,删除内部监听实例。