验证码发送按钮必须点击即禁用并启动服务端对齐的倒计时,失败时需还原状态,且须用语义化button配合aria属性保障可访问性。

点击后禁用按钮并倒计时,防止重复提交
用户点一次就发多条验证码,本质是没控制按钮状态。必须在 onclick 里立刻禁用按钮,并启动倒计时,否则网络稍慢时容易连点触发多次请求。
- 禁用用
button.disabled = true,别只靠 CSS 隐藏或加 class 模拟禁用——那不阻止事件触发 - 倒计时建议用
setInterval,但务必保存返回的 timer ID,倒计时结束前要clearInterval,否则内存泄漏 - 倒计时结束后记得恢复按钮状态:
button.disabled = false和重置文案(比如从“60s”变回“发送验证码”)
后端返回错误时,按钮状态要正确还原
很多人只处理成功路径,但网络失败、验证码超频、手机号格式错等情况一来,按钮就卡在“已禁用”状态,用户没法重试。
- 所有异步请求的
catch或error回调里,必须执行按钮还原逻辑 - 推荐封装一个
resetSendButton(button)函数,统一处理文案、disabled、loading 状态,避免漏写 - 如果后端返回了具体错误码(如
4001表示“发送太频繁”),可以顺便在按钮旁显示提示,但别覆盖原有 DOM 结构,用span动态插入更稳妥
用 button 而不是 a 或 div
语义和可访问性问题常被忽略。a 标签没有原生 disabled 属性,div 不支持键盘回车触发,屏幕阅读器也读不出它是操作控件。
- 必须用
<button type="button"></button>,type="button"防止表单意外提交 - 加
aria-busy="true"和aria-disabled="true"(配合 JS 同步更新),辅助技术能感知状态变化 - 别用
pointer-events: none替代disabled——它不改变键盘焦点行为,也不影响屏幕阅读器播报
倒计时时间与后端限制对齐
前端倒计时设成 60 秒,但后端只允许 61 秒后重发?那第 61 秒点下去照样失败。时间必须以服务端为准。
- 后端接口应返回剩余可发送时间(如
{"remaining": 52}),前端据此启动倒计时,而非硬编码 60 - 如果后端没返回,至少在请求前先 GET 一次校验接口(如
/api/verify/sendable?phone=138xxxx),拿到准确remaining - 倒计时到 0 后,不要自动重发,只开放点击;重发前必须再调一次校验,防止用户手动改时间绕过限制
倒计时逻辑看着简单,但状态同步、错误兜底、服务端一致性这三点漏掉任一个,都会让验证码功能在线上变得不可靠。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











