vue 3 验证码倒计时按钮应分层封装:抽离 usecountdown 组合式函数管理倒计时状态与生命周期,按钮组件专注交互反馈,集成防连点、请求保护及 localstorage 持久化实现刷新续计。

在 Vue 3 中封装一个可复用、健壮的验证码倒计时按钮,核心不是堆功能,而是分层清晰、状态可控、副作用可管理。它本质上是一个「带状态的按钮」,但要兼顾防连点、定时器清理、响应式更新、本地持久化等真实场景需求。
拆出独立的倒计时逻辑(useCountDown)
把倒计时行为抽成组合式函数,是 Vue 3 封装的关键习惯。它不依赖 UI,只负责时间管理与状态暴露:
- 接收初始秒数(如 60)、是否自动启动等配置
- 返回 count(当前剩余秒数)、isActive(是否正在倒计时)、start、reset、pause 等方法
- 内部用
setInterval,并在组件卸载或重置时调用clearInterval,避免内存泄漏 - 用
ref存秒数,用onBeforeUnmount或onScopeDispose清理定时器(尤其页面跳转/销毁时)
按钮组件支持基础交互控制
倒计时按钮本身应专注「点击触发 + 状态反馈」,不耦合业务逻辑:
- 通过
v-model:disabled或:disabled控制禁用态,配合count > 0实现视觉锁定 - 按钮文案动态切换:
{{ count > 0 ? count + 's 后重发' : '获取验证码' }} - 暴露
@click事件,但仅在count === 0且未处于倒计时中才触发(防止用户绕过禁用直接调用) - 支持传入
size、type、loading等常见 props,与 Element Plus 或 Naive UI 风格对齐
集成防连点与请求保护
单纯禁用按钮不够——后端接口仍可能被恶意重复调用。需在业务层加防护:
- 发送前校验手机号格式,为空或非法直接 return
- 用 ref 记录「是否已发起请求」,如
isSending.value = true,请求完成或失败后设为 false - 倒计时开始前先调用接口,成功后再
start();若接口报错(如频次超限),立即reset()并提示用户 - 避免将倒计时和请求逻辑写死在组件内,推荐由父组件调用
sendCode()方法,子组件只负责展示与触发
增强体验:支持刷新后倒计时延续
用户刷新页面,倒计时不应归零。可通过 localStorage 持久化关键状态:
- 倒计时启动时,记录开始时间戳 + 总时长,存入 localStorage(如
{ start: 1727251620000, total: 60 }) - 组件挂载时读取该数据,计算剩余秒数:
Math.max(0, total - (Date.now() - start)) - 若剩余 > 0,则自动启动倒计时;否则清空 storage,恢复初始态
- 注意:localStorage 是字符串存储,需 JSON.parse / JSON.stringify 处理
这样封装出来的组件,既可单独使用,也能嵌入 FormItem、登录弹窗、注册流程等任意表单场景,逻辑隔离、职责明确、易于测试和维护。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











