onUnmounted清理必须统一规范、可验证、无遗漏,严格覆盖定时器、全局事件监听器、WebSocket、第三方库实例、watch类监听器五类资源,并满足ref管理、判空检查、置空三硬性要求。

团队代码审查中,onUnmounted(或 beforeUnmount)钩子的清理逻辑必须统一、可验证、无遗漏。它不是“有就行”,而是要形成可检查、可自动化、防漏判的规范标准。
明确哪些资源必须清理
审查时直接对标以下五类资源,任一出现就必须有对应清理动作:
- 定时器(
setInterval/setTimeout)——必须调用clearInterval或clearTimeout - 全局事件监听器(
window.addEventListener、document.addEventListener)——必须配对调用removeEventListener - WebSocket 或长连接实例——必须调用
.close(),且建议检查readyState - 第三方库实例(ECharts、Mapbox、Monaco Editor 等)——必须调用其
dispose()、destroy()或dispose()方法 - 手动创建的
watch、watchEffect、$subscribe等监听器——必须调用其返回的stop函数
清理写法必须满足三项硬性要求
审查不看风格,只验行为。以下三点任一不满足即为不合规:
-
引用必须用 ref 管理:定时器 ID、socket 实例、chart 对象等,须声明为
const timer = ref(null),禁止直接赋值给普通变量(如let timer),否则无法在onUnmounted中安全访问 -
清理前必须判空:所有
clearInterval、.close()、stop()调用前需加if (xxx.value)或if (xxx),避免对 null/undefined 执行操作 -
清理后必须置空:清除后需显式设为
null(如timer.value = null),既防止重复清理报错,也便于调试时快速识别状态
keep-alive 场景需双钩子覆盖
若组件被 包裹(如路由级缓存页),onUnmounted 不会触发。审查时需确认是否同时处理了:
-
onDeactivated中执行全部清理动作(与onUnmounted内容一致) -
onActivated中检查资源是否已存在,仅在为空时才重新初始化(防重复启动定时器或连接) - 若组件可能以两种方式复用(缓存 + 非缓存),则
onUnmounted和onDeactivated必须共存,二者清理逻辑完全一致
推荐引入自动化检查手段
人工审查易漏,建议落地轻量机制:
- ESLint 插件规则:启用
@vue/vue3-no-unused-reactive+ 自定义规则,检测onUnmounted中是否遗漏对 setup 内声明的副作用引用的清理 - 代码模板约束:在团队脚手架或 IDE 模板中,预置带注释的
onUnmounted块,含常见清理项占位符和空值判断样板 - PR 检查清单:在 MR 描述模板中强制勾选 “✅ 已检查 onUnmounted 清理逻辑” 并附简要说明(如:“已清 timer、socket、watch”)
规范不是限制发挥,而是把“容易忘”变成“没法漏”。只要资源创建在 setup 里,清理就锁死在 beforeUnmount/onUnmounted 里,引用用 ref 管,清完设 null——这条主线守住,内存泄漏风险就基本归零。











