oncleanup 是 watcheffect 内置的清理机制,用于在副作用被覆盖或组件卸载前清理异步资源;必须同步注册,适用于取消请求、清除定时器、移除事件监听等场景。

onCleanup 是 watchEffect 内置的清理注册机制,专门用来处理异步副作用(比如请求、定时器、事件监听)被中断时的善后工作。它不是每次 effect 执行完都运行,而是在当前副作用即将被覆盖(依赖变化触发重跑)或组件卸载前,自动调用上一次注册的清理函数。
onCleanup 必须同步调用
它只能在 watchEffect 回调的同步执行阶段注册,不能放在 await 后面、setTimeout 里,也不能异步延迟调用。一旦进入异步上下文,Vue 就无法将清理逻辑绑定到当前副作用实例上,会直接报错。
- ✅ 正确:在 fetch 或 setTimeout 调用前,立刻调用 onCleanup(() => {...})
- ❌ 错误:await fetchData(); onCleanup(...) —— 此时已脱离响应式追踪上下文
取消未完成的 API 请求
这是最典型的应用场景。用户快速输入搜索词时,旧请求必须及时终止,避免响应错乱或状态覆盖。
- 创建 AbortController 实例,把 signal 传给 fetch/axios
- 在 onCleanup 中调用 controller.abort(),主动中断请求
- catch 中判断 err.name !== 'AbortError',只处理真实错误
清理定时器和事件监听器
除了网络请求,任何长期存在的资源都需要手动释放:
- 用 setInterval 启动轮询 → onCleanup 中调用 clearInterval
- 监听 window.resize → onCleanup 中 removeEventListener
- 初始化 ECharts / Mapbox 等第三方实例 → onCleanup 中调用 dispose() 或 destroy()
注意组件卸载时的兜底保障
watchEffect 的 onCleanup 在组件 unmount 时也会触发,但前提是该副作用当时仍处于活跃状态。如果副作用因依赖变化已提前停止,最后一次注册的 onCleanup 仍会被执行;不过为保险起见,涉及 DOM 或外部库实例时,建议配合 onBeforeUnmount 做二次检查销毁。










