必须在 onBeforeUnmount 中清除验证码倒计时定时器,因其执行时组件实例仍可用;定时器 ID 需用 ref 保存并配合防连点锁 isSending,确保同一时间仅一个定时器运行且卸载时可靠清理。

验证码倒计时定时器必须在组件卸载前清除,否则会持续运行、触发内存泄漏,甚至导致页面跳转后仍执行回调、报 Cannot read property 'xxx' of null 错误。Vue 3 推荐使用 onBeforeUnmount 钩子来销毁定时器,这是最安全、最语义明确的时机。
为什么选 onBeforeUnmount 而不是 onUnmounted
onBeforeUnmount 触发时,组件实例仍完全可用:响应式数据、ref、DOM 引用都有效;而 onUnmounted 执行时,组件已解绑,this 或 ref.value 可能为 null 或 undefined,无法可靠访问定时器 ID。
- onBeforeUnmount 是“卸载前”的最后一道可控入口,适合做资源清理
- onUnmounted 更适合作日志记录或异步收尾,不建议用于依赖响应式状态的操作
- 官方文档与主流实践(如 Auth0、ECharts 集成)均优先推荐 onBeforeUnmount
定时器 ID 必须用 ref 保存,不能用 let/const 变量
如果用普通变量存储 setInterval 返回值,在 setup 中多次调用倒计时函数(比如用户重复点击发送按钮),旧的定时器 ID 会被覆盖,导致无法清除——这是最常见的内存泄漏原因。
审查 Vue 管理后台的变更请求(Vue 2 + Element UI,Vue 3 + Element Plus)。重点关注最小化变更实现、上线风险检查以及回归检查清单生成。
- 正确做法:用
const timer = ref<nodejs.timeout null>(null)</nodejs.timeout>声明 - 启动时先清空旧定时器:
if (timer.value) clearInterval(timer.value) - 赋新值:
timer.value = setInterval(...) - 卸载时统一清除:
onBeforeUnmount(() => { if (timer.value) clearInterval(timer.value) })
配合防连点逻辑,避免重复创建定时器
用户快速点击“获取验证码”按钮,可能触发多个定时器同时运行。除了用 ref 管理 ID,还需加状态锁:
- 定义
const isSending = ref(false) - 点击时先判断:
if (isSending.value || codeNum.value !== 60) return - 发送请求前设为 true,成功后启动定时器,倒计时结束再设回 false
- 这样既能防止连点,又能确保同一时间最多一个定时器活跃
页面离开时自动销毁,不依赖用户操作
用户通过路由跳转、关闭标签页、前进后退等方式离开当前组件,onBeforeUnmount 会自动触发,无需额外监听。但要注意:
- 不要在 onUnmounted 里写清除逻辑,它不可靠
- 若使用了全局事件(如 window.addEventListener),也需在同一个 onBeforeUnmount 中 removeEventListener,且 handler 必须是同一函数引用(不能用箭头函数)
- 倒计时结束时主动清空 timer.value,并重置倒计时值,避免残留状态影响下次使用
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










