组件卸载时需主动清理资源,主要通过onBeforeUnmount清理定时器、事件监听器、第三方实例等;watchEffect的onInvalidate用于中断延迟副作用;effectScope可统一管理并自动停止一组副作用;第三方库和自定义事件须显式解绑。

组件注册本身不负责卸载时的注销,真正起作用的是生命周期钩子配合资源管理策略。关键不是“注册时做什么”,而是“注册后创建了什么资源,以及如何在卸载前把它们关掉”。
用 onBeforeUnmount 清理显式创建的外部资源
这是最直接、最常用的方式,适用于你主动启动或绑定的非响应式资源:
- 定时器(setInterval / setTimeout):保存 ID 引用,在卸载前 clearInterval 或 clearTimeout
- 全局事件监听器(window.addEventListener):用同一函数引用调用 removeEventListener
- 第三方实例(ECharts、WebSocket、Mapbox):调用其 .dispose()、.close() 或 .remove() 方法
- 未完成的 fetch 请求:配合 AbortController,在卸载前调用 abort()
watchEffect 中用 onInvalidate 中断本轮异步操作
当副作用依赖响应式数据且存在延迟(如防抖、轮询、pending 请求),仅靠卸载时机清理可能太晚。这时应利用 watchEffect 的清理回调:
将静态 Vue 页面(index.vue)改造为动态页面(Custom.vue);稿源仅限 index.vue、其引用的 CSS 与资源路径,禁止参考仓库内其他文件。Invoke when user wants to transform a static Vue page into a dynamic data-driven page with Element UI components.
- 每次新响应触发前,上一轮的 onInvalidate 自动执行
- 适合 clearTimeout、abort fetch、移除临时事件监听等“中断当前动作”的场景
- 它不替代 onBeforeUnmount,而是补充——处理“还没到卸载,但旧逻辑该停了”的情况
用 effectScope 统一管理一组副作用
当你在一个组合式函数中创建多个 watch、watchEffect 或 computed,又希望一键释放,effectScope 是更结构化的选择:
- 调用 const scope = effectScope() 创建独立作用域
- 所有副作用写在 scope.run(() => { ... }) 内,自动归属该 scope
- 组件卸载时 Vue 自动调用 scope.stop();跨组件或工具函数中可手动调用
- 比逐个清理更可靠,尤其适合封装可复用逻辑
对第三方库或自定义事件做显式解绑
有些资源 Vue 不感知,必须你来负责:
- 通过 $on 绑定的自定义事件:卸载前调用 $off(Composition API 中较少见,多见于 Options API)
- 使用 store.$subscribe 或 watch 时未调用返回的 stop 函数:记得保存并调用
- 动态插入的 DOM 节点或 iframe:手动 removeChild 或 .remove()
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










