Vben-Admin 框架中验证码倒计时动态更新解决方案
Vben-Admin 框架中验证码倒计时动态更新解决方案一、Vben-Admin 是什么Vben-Admin是一个基于Vue 3 TypeScript Vite的现代化企业级中后台管理系统框架。它提供了开箱即用的权限管理、路由配置丰富的 UI 组件库基于 Ant Design Vue 封装强大的表单、表格组件系统统一的登录/认证模块vben/common-ui其中的AuthenticationCodeLogin和VbenPinInput组件就是框架内置的验证码登录解决方案。二、为什么会出现这个需求业务场景用户登录时通过手机号 短信验证码的方式。后端接口有以下逻辑验证码未过期时→ 不重复发送短信直接返回已存在的验证码的expire_at验证码已过期或不存在时→ 生成新验证码并发送短信核心需求前端倒计时必须与后端验证码的有效期实时同步场景后端返回expire_at期望倒计时首次请求2026-08-08 14:05:005分钟后300 秒30 秒后再次请求验证码未过期2026-08-08 14:05:00不变270 秒4 分 50 秒后再次请求快过期了2026-08-08 14:05:00不变10 秒5 分钟后再次请求已过期2026-08-08 14:10:00新时间300 秒一句话用户看到的倒计时 当前验证码的真实剩余有效时间每次点击获取验证码按钮都与后端同步校验无缝续期。三、遇到的问题3.1 一开始以为handleSendCode返回值控制倒计时根据VbenPinInput的 props 定义我们以为handleSendCode的返回值会控制倒计时秒数// ❌ 直觉上以为这样就能控制倒计时handleSendCode:async(){// ... 发送验证码 ...return300;// 以为返回 300 就能倒计时 300 秒}3.2 实际测试发现返回无效当我们测试handleSendCode: async () { return 20; }时倒计时仍然显示 60 秒。3.3 查看组件源码发现真相通过查看VbenPinInput组件源码发现其内部逻辑是// VbenPinInput 组件内部简化const{maxTime60,// ← 倒计时秒数来自这里handleSendCodeasync(){},}definePropsPinInputProps();constcountdownref(0);asyncfunctionhandleSend(e:Event){awaithandleSendCode();// ← 只是执行忽略返回值countdown.valuemaxTime;// ← 直接用 maxTime 作为倒计时startCountdown();// ← 每秒减 1}结论handleSendCode的返回值完全被忽略倒计时秒数由maxTimeprops 决定。四、解决方案4.1 核心思路利用 Vue 的响应式数据特性用ref动态绑定maxTime// 1. 定义响应式变量初始 60 秒constmaxTimeref(60);// 2. 在 handleSendCode 中更新它consthandleSendCodeasync(){constresawaitsendCodeApi({phone});if(res.data.expire_at){constsecondsgetSecondsRemaining(res.data.expire_at);maxTime.valueseconds0?seconds:60;// ✅ 更新倒计时}};// 3. 传给 VbenPinInputcomponentProps:{maxTime:maxTime,// ← 响应式绑定值变了组件自动更新}4.2 完整代码script langts setup import { computed, ref } from vue; import { AuthenticationCodeLogin, z } from vben/common-ui; import { $t } from vben/locales; import { message } from ant-design-vue; import { sendCodeApi } from #/api; // 1. 响应式倒计时秒数 const maxTime ref(60); // 2. 计算剩余秒数 const getSecondsRemaining (dateString: string) { const diffMs new Date(dateString).getTime() - new Date().getTime(); return Math.floor(diffMs / 1000); }; // 3. 发送验证码 const handleSendCode async () { try { const res await sendCodeApi({ phone: currentPhone }); if (res.code 0) { if (res.data.expire_at) { const seconds getSecondsRemaining(res.data.expire_at); // ✅ 关键更新响应式变量 maxTime.value seconds 0 ? seconds : 60; } } } catch (error) { // 错误处理... } }; // 4. 表单配置 const formSchema computed((): VbenFormSchema[] [ { component: VbenInput, fieldName: phone, // ... }, { component: VbenPinInput, fieldName: code, componentProps: { codeLength: 6, maxTime: maxTime, // ✅ 响应式绑定 createText: (countdown: number) { return countdown 0 ? ${countdown} 秒后重发 : 获取验证码; }, handleSendCode: handleSendCode, }, // ... }, ]); /script4.3 数据流图用户点击按钮 │ ▼ handleSendCode() │ ▼ sendCodeApi() → 后端返回 { expire_at } │ ▼ getSecondsRemaining(expire_at) → 计算剩余秒数 │ ▼ maxTime.value 剩余秒数 ← 响应式更新 │ ▼ VbenPinInput 内部 countdown.value maxTime ← 组件收到新值 │ ▼ 倒计时按新的秒数开始运行五、总结项目内容框架Vben-Admin 的vben/common-ui认证模块组件VbenPinInput验证码输入倒计时误区误以为handleSendCode返回值控制倒计时真相maxTimeprops 才是倒计时秒数的唯一来源解法用ref响应式绑定maxTime在handleSendCode中动态更新效果倒计时始终与后端expire_at保持同步

相关新闻

免费降AI率工具为什么越改越高?怎么免费把AIGC疑似度降下来?

免费降AI率工具为什么越改越高?怎么免费把AIGC疑似度降下来?

免费降AI率工具为什么越改越高?怎么免费把AIGC疑似度降下来? 你是不是轮流用了DeepSeek、豆包和几个免费小程序,每个都把文字改得更顺,AI率却一次比一次高?更麻烦的是,原稿还能看出自己的写作习惯&#xff…

2026/9/23 9:25:34 阅读更多 →
西门子200 SMART PLC在自动化产线中的集成应用与优化

西门子200 SMART PLC在自动化产线中的集成应用与优化

1. 项目概述:西门子200smart在自动化产线中的集成应用这个案例展示了西门子S7-200 SMART PLC在工业自动化领域的典型应用场景——通过脉冲定位控制伺服系统,实现自动输送抓料与自动移印机的协同作业。作为一款经济型PLC,200 SMART系列凭借其稳…

2026/9/24 5:49:12 阅读更多 →
UE4 3DUI穿模解决方案:基于深度检测的智能透视材质实现

UE4 3DUI穿模解决方案:基于深度检测的智能透视材质实现

1. 项目概述:从“穿模”到“透视”的UI视觉革命在虚幻引擎4(UE4)里做3DUI,最让人头疼的莫过于“穿模”问题。你精心设计了一个悬浮在角色面前的3D血条、一个漂浮在空中的任务指示器,或者一个附着在武器上的弹药计数器&…

2026/9/23 19:29:02 阅读更多 →

最新新闻

RenderDoc Python API 捕获指南:进程执行、注入与目标控制(Capturing)全解析

RenderDoc Python API 捕获指南:进程执行、注入与目标控制(Capturing)全解析

开发工具调试器图形学GPU 【免费下载链接】renderdoc RenderDoc is a stand-alone graphics debugging tool. 项目地址: https://gitcode.com/gh_mirrors/re/renderdoc 点击查看 免费下载 本指南围绕 RenderDoc Python 模块 renderdoc 中与"捕获(C…

2026/9/24 6:25:26 阅读更多 →
从数据源到产品落地,这些媒体源头API服务商值得信赖

从数据源到产品落地,这些媒体源头API服务商值得信赖

把上游数据接进自家产品之后,最先遇到的问题往往不是数据不够,而是数据用不出结果。 接口能返回内容,报表也能生成,可当产品要给出一个“这次投放值不值”的结论时,团队会发现中间还缺一层转换:接口给的是事…

2026/9/24 6:25:26 阅读更多 →
大白话说Spring全家桶-34-Sentinel限流熔断

大白话说Spring全家桶-34-Sentinel限流熔断

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 6:25:25 阅读更多 →
DeepSeek应用一体机私有化部署:硬件选型与场景落地指南

DeepSeek应用一体机私有化部署:硬件选型与场景落地指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 6:25:25 阅读更多 →
空气动力学PDF资料实战指南:从无量纲数到CFD仿真落地

空气动力学PDF资料实战指南:从无量纲数到CFD仿真落地

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 6:25:24 阅读更多 →
大白话说Spring全家桶-35-Seata分布式事务

大白话说Spring全家桶-35-Seata分布式事务

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 6:24:24 阅读更多 →

日新闻

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为…

2026/9/24 0:00:19 阅读更多 →
单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

简介:一份基于单细胞RNA测序数据的细胞类型注释算法研究Python毕业设计源码,针对计算机相关专业正在做毕设或需要项目实战的学习者,可用于课程设计与期末大作业。项目代码完整、经导师指导评审通过,可直接运行,覆盖数据…

2026/9/24 0:00:19 阅读更多 →
C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

第一次在项目里被反射卡住,是在一个老旧的WinForms模块里:几十个类依赖PropertyChanged通知,运行时反射读属性、发通知,每次启动慢半拍不说,一上.NET Native/AOT裁剪模式几乎全面崩盘。后来我把这段逻辑全部改成C#源生…

2026/9/24 0:00:19 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/23 4:55:02 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/23 4:49:06 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/23 9:53:41 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/23 9:53:40 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/23 9:53:40 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/23 9:53:40 阅读更多 →