watcheffect 本身不支持暂停恢复,需用响应式开关(如 ispaused)控制副作用是否执行;每次触发时检查开关,为 true 则直接返回;结合页面可见性可实现自动暂停恢复;vue 3.5+ 的 watch 支持 pause/resume,但 watcheffect 不适用。

watchEffect 本身不支持暂停恢复,需靠状态控制
watchEffect 没有内置的 pause/resume 方法——它设计为“响应即执行”,一旦依赖变化就立刻运行副作用。所谓“暂停恢复”,本质是**用响应式开关控制副作用是否实际执行**,而不是让 watchEffect 自身挂起。核心思路是:在 effect 内部加条件判断,跳过逻辑体;恢复时依赖更新自动触发。
用 ref 控制执行开关
定义一个响应式标志位,比如 isPaused = ref(false),并在 watchEffect 中读取它:
- 每次副作用执行前检查 if (isPaused.value) return,直接退出
- 用户点击“暂停同步”时设 isPaused.value = true,后续依赖变化仍会触发 watchEffect,但内部逻辑被跳过
- 点击“恢复”时设 isPaused.value = false,下一次依赖变化就会正常执行
结合页面可见性做自动暂停
常见场景如视频进度同步、定时上报,需在标签页切走时自动暂停,切回时恢复:
- 用 const isVisible = ref(!document.hidden) 跟踪页面可见性
- 监听 visibilitychange 事件更新 isVisible
- 在 watchEffect 中写 if (!isVisible.value || isPaused.value) return
- 这样无需手动点按钮,也能实现“离开即停、回来即续”的自然行为
Vue 3.5+ 的 watch 支持 pause/resume,但 watchEffect 不行
注意区分:Vue 3.5 引入的 pause/resume 是 watch 函数返回对象的方法,对 watchEffect 不适用。如果你需要开箱即用的暂停能力,可考虑改用 watch,并把依赖包装成 getter:
- 例如:const { pause, resume } = watch(() => videoRef.value?.currentTime, handler)
- 但 watchEffect 的优势在于自动追踪、写法简洁,牺牲暂停 API 换来更少样板代码
- 真要暂停 watchEffect,还是推荐用 isPaused + 条件判断,逻辑清晰且兼容所有版本











