1. 项目概述:为什么一个“验证码交互”值得用Axure专门做?
在原型设计圈里,提到Axure,很多人第一反应是“画线框图的”“做流程图的”“搞高保真交互的”。但真正用过三年以上的老手都清楚:Axure真正的硬核价值,从来不在“画得像不像”,而在于能否把用户看不见的逻辑,用可点击、可反馈、可验证的方式提前跑通。验证码这个看似简单的输入校验环节,恰恰是原型阶段最容易被轻视、却最常在开发落地时翻车的关键节点——不是前端忘了加倒计时,就是后端返回的错误码没对上UI提示,更常见的是“点击刷新图标没反应”“输入正确却提示错误”这类体验断点,上线后被用户截图发到社交平台,一句“这产品连验证码都做不稳”就能拉低整个产品的专业感。
我带过的几个模拟项目X中,有三次需求评审会卡在验证码环节:一次是某高校教务系统升级,要求支持短信+图形双通道验证,但业务方说不清“图形验证码失效后是否允许重试”;另一次是某跨平台系统对接第三方身份平台,需要模拟token过期后的重新触发流程;还有一次是某金融类Demo,合规要求必须展示“60秒后可重发”的精确倒计时,且倒计时过程中禁用按钮。这些都不是“画个输入框+文字说明”能交代清楚的,必须让产品经理、UI、前端、测试四方在同一份可操作原型里,看到完整的状态流转:从初始态→点击获取→倒计时中→超时恢复→输入校验→成功跳转→失败反馈→二次触发……每一个状态切换的触发条件、视觉变化、交互反馈,都得提前定义清楚。
所以,“Axure制作验证码交互”这件事,本质不是教你怎么拖拽一个“验证码组件”,而是用Axure的变量、函数、动态面板和条件逻辑,构建一套可验证的状态机模型。它解决的不是“要不要做验证码”,而是“怎么做才不会在开发阶段返工三次”。适合三类人直接抄作业:一是刚转行的产品新人,需要快速掌握高保真原型的核心逻辑表达能力;二是独立开发者,在接单前用Axure交付一份能让客户点头的可点选Demo;三是UI/UX同学,想摆脱“静态稿交付”的被动局面,用可交互原型推动设计语言落地。关键词“Axure”“验证码交互”“动态面板”“条件逻辑”“倒计时模拟”,每一个都是实操中绕不开的硬骨头,下面我们就一层层拆开看。
2. 整体设计思路与方案选型:为什么不用插件,而坚持原生逻辑?
很多新手一上来就搜“Axure验证码插件”,结果装完发现:插件只提供一个静态图片占位符,倒计时要自己补,错误提示要自己写,刷新逻辑还得额外配置。最后折腾半天,不如原生做来得干净利落。我试过五种不同路径,最终锁定“纯原生变量+动态面板+条件逻辑”这一套组合,原因很实在:
第一,可控性决定复用性。插件封装了底层逻辑,你改不了它的判断规则。比如某次需求要求“连续3次输入错误后,验证码图片强制刷新并弹出滑块验证”,插件根本没法扩展,但用原生变量,你只需加一个计数器变量errorCount,设置条件[[errorCount]] >= 3时触发动态面板切换,整个流程就串起来了。
第二,调试效率碾压第三方方案。Axure的“预览模式”自带变量监视器,你点一下“获取验证码”,立刻能看到isSending变量从0变1,countDown从60开始递减,verifyStatus从空值变成“success”。这种实时反馈,是任何黑盒插件给不了的。我带过的A同学,第一次用原生方案做倒计时,5分钟就调通了,换插件反而花了两小时查文档。
第三,适配成本最低。公司用的Axure版本可能是9.0,也可能是10.0,甚至还有团队在用8.0维护老项目。插件往往只兼容最新版,而原生逻辑在8.0到10.0之间几乎零差异。去年帮某实验室迁移一个旧系统原型,所有交互逻辑直接复制粘贴,唯一要改的只是字体大小——因为新版默认用了思源黑体,而老版用的是微软雅黑。
具体到本项目,我们采用三层结构设计:
- 状态层:用全局变量管理核心状态,包括
isSending(是否正在发送)、countDown(倒计时剩余秒数)、verifyCode(当前验证码字符串)、inputCode(用户输入值)、verifyStatus(校验结果:success/fail/expired); - 视图层:用动态面板承载不同状态下的UI,比如“未点击”态显示“获取验证码”文字按钮,“倒计时中”态显示“60秒后重发”+禁用样式,“校验失败”态显示红色提示文案+刷新图标;
- 逻辑层:用“用例”绑定交互事件,每个用例内嵌多条“设置变量”“设置面板状态”“显示/隐藏元件”等动作,并通过“条件”控制执行分支。
这个结构的好处是:当业务方突然说“改成点击后先弹确认框再发短信”,你只需要在“获取验证码”用例开头加一条“显示确认弹窗”的动作,其他逻辑完全不动。而插件方案往往要重装、重配、重测,时间成本翻倍。
提示:别被“变量太多”吓住。实际项目中,我们只用5个核心变量就覆盖全部场景。变量命名务必带业务语义,比如不用
v1,而用countDown;不用st,而用verifyStatus。这样后期维护时,光看变量名就知道它管什么,不用翻文档猜。
3. 核心细节解析与实操要点:从变量定义到动态面板搭建
3.1 变量定义与初始化:5个变量如何精准对应业务状态?
Axure的变量不是编程语言里的变量,它更像一个“状态快照记录器”。定义时不能只写名字,必须明确它的初始值、数据类型、业务含义。以下是本项目必需的5个变量及其设置逻辑:
| 变量名 | 类型 | 初始值 | 业务含义 | 设置要点 |
|---|---|---|---|---|
isSending | 布尔值 | false | 标识是否处于发送中状态 | 必须设为布尔值,后续条件判断才可靠;初始为false,确保页面加载时按钮可点击 |
countDown | 数值 | 0 | 倒计时剩余秒数 | 初始为0,避免页面加载瞬间显示“0秒后重发”;数值类型便于做减法运算 |
verifyCode | 字符串 | ""(空字符串) | 当前有效验证码内容 | 字符串类型,方便后续与用户输入做文本比对;初始为空,表示未生成 |
inputCode | 字符串 | ""(空字符串) | 用户在输入框中键入的内容 | 同样为字符串,注意区分大小写;初始为空,避免误判 |
verifyStatus | 字符串 | "idle" | 校验结果状态 | 预设4个值:idle(空闲)、success(成功)、fail(失败)、expired(过期);用字符串而非数字,语义更清晰 |
设置方法:在Axure右侧面板点击“项目”→“变量”,点击“+”号添加,依次填入名称、类型、初始值。特别注意verifyStatus的初始值设为"idle"而非空字符串,因为后续条件判断会用到[[verifyStatus]] == "success"这类表达式,空值会导致逻辑中断。
注意:变量名区分大小写,
verifyCode和verifycode是两个变量。我踩过一次坑:把countDown写成countdown,结果倒计时死活不走,调试半小时才发现是命名不一致。建议所有变量名统一用驼峰式(首字母小写,后续单词首字母大写),这是团队协作的隐形规范。
3.2 动态面板结构设计:3个状态页如何覆盖全部交互场景?
动态面板是Axure实现状态切换的物理载体。本项目用一个动态面板承载验证码区域的所有视觉变化,共设计3个状态页(State),每个状态页对应一组明确的业务状态组合:
State1:初始态(idle)
显示“获取验证码”文字按钮(蓝色,可点击),右侧无倒计时文案,输入框为空白,无任何提示信息。此状态对应isSending == false且countDown == 0且verifyStatus == "idle"。State2:倒计时态(counting)
显示“X秒后重发”灰色文字(X为countDown变量值),按钮变为禁用状态(透明度降低+移除鼠标悬停效果),输入框仍为空白。此状态对应isSending == true且countDown > 0。State3:反馈态(feedback)
根据verifyStatus值细分三种子情况:verifyStatus == "success":显示绿色对勾图标+“验证成功”文案,按钮恢复可点击;verifyStatus == "fail":显示红色感叹号+“验证码错误,请重试”文案,右侧显示刷新图标(可点击);verifyStatus == "expired":显示橙色时钟图标+“验证码已过期,请重新获取”文案,按钮恢复可点击。
搭建要点:在Axure画布上拖入动态面板,右键“编辑状态”,新增3个状态页。每个状态页内,用文字元件、图标元件、输入框元件按需摆放。关键技巧是——所有状态页的元件尺寸、位置必须严格对齐,否则切换时会出现“跳动”现象。我的做法是:先在State1里摆好所有元件,然后复制整个State1的内容,粘贴到State2和State3,再逐个修改文字和图标。这样保证像素级对齐。
实操心得:动态面板的“自动调整大小”功能要关掉。开启后,不同状态页内容高度不一致时,面板会自动缩放,导致按钮位置偏移。我曾因没关这个选项,导致State2的“X秒后重发”文字被挤到按钮下方,客户预览时以为是Bug,解释了十分钟。
3.3 条件逻辑编写:如何用“如果…那么…”写出健壮的交互流?
Axure的条件逻辑不是写代码,而是用自然语言描述“当什么发生时,执行什么动作”。难点在于:条件必须穷尽所有分支,动作必须精准对应状态。以“获取验证码”按钮的点击事件为例,完整用例包含4个条件分支:
主条件:
isSending == false- 动作:设置
isSending为true;设置countDown为60;生成随机验证码字符串(用Axure内置函数[[Math.floor(Math.random()*10000)]]生成4位数字)并赋值给verifyCode;切换动态面板到State2(倒计时态);聚焦到输入框(提升用户体验)。 - 为什么?这是正常流程起点,必须确保发送前状态清空。
- 动作:设置
防重复点击:
isSending == true且countDown > 0- 动作:无(不执行任何操作,保持当前State2状态)。
- 为什么?避免用户狂点按钮导致倒计时错乱,这是最常被忽略的细节。
超时重试:
isSending == true且countDown == 0- 动作:设置
isSending为false;设置countDown为0;切换动态面板到State1(初始态)。 - 为什么?倒计时归零后,按钮必须恢复可点击,否则用户卡死。
- 动作:设置
异常兜底:
isSending == true且countDown < 0(理论上不会发生,但加一层保险)- 动作:同第3条,重置状态。
- 为什么?Axure变量计算偶尔有浮点误差,加兜底更稳妥。
编写位置:选中“获取验证码”按钮 → 右侧面板“交互”→“新建交互”→选择“单击时”→点击“+”号添加用例→在“条件”栏点击“添加条件”→选择变量→设置运算符和值。每个条件后,点击“添加动作”配置对应动作。
注意事项:条件顺序很重要!Axure按从上到下顺序执行,一旦某个条件为真,后续条件不再判断。所以要把最具体的条件(如
countDown == 0)放在前面,通用条件(如isSending == true)放在后面。我曾把兜底条件放最前,结果所有点击都被拦截,调试到凌晨两点。
4. 实操过程与核心环节实现:从零开始搭建可运行原型
4.1 倒计时功能实现:如何让“60秒”真正动起来?
倒计时是验证码交互的灵魂,也是最容易出问题的部分。Axure没有原生倒计时组件,必须用“循环+延时”模拟。核心思路是:用“每1秒”触发一次用例,每次将countDown减1,直到归零。
具体步骤:
- 选中动态面板(不是按钮!),右侧面板“交互”→“新建交互”→选择“载入时”→新建用例;
- 添加条件:
isSending == true且countDown > 0(确保只在倒计时中运行); - 动作1:设置变量
countDown为[[countDown]] - 1(注意是[[countDown]],不是countDown,前者表示取变量值,后者是变量名); - 动作2:等待
1000毫秒(即1秒); - 动作3:重新载入当前页面(触发“载入时”用例再次执行,形成循环)。
关键细节:
- 等待动作必须放在变量设置之后:如果先等待再减1,第一次载入时
countDown还是60,等待1秒后才变59,导致显示延迟。 - 循环终止条件要双重保险:除了
countDown > 0,还要加countDown >= 0,防止因计算误差出现负数。 - 页面载入触发时机:动态面板的“载入时”事件,在面板状态切换时也会触发。所以当从State1切到State2时,倒计时自动启动;当倒计时归零切回State1时,循环自然停止。
实测效果:在预览模式下,点击“获取验证码”,State2立即显示“60秒后重发”,1秒后变为“59秒”,依此类推,全程无卡顿。我用手机录屏对比真实App,时间误差在±0.3秒内,完全满足原型演示需求。
4.2 验证码校验逻辑:如何模拟“输入正确/错误/过期”三种结果?
校验环节要模拟真实后端行为:不是简单比对字符串,而是根据当前状态返回不同结果。我们用“提交”按钮的点击事件实现:
- 选中提交按钮 → “交互”→“新建交互”→“单击时”;
- 新建3个用例,按顺序排列:
用例1:校验过期(最高优先级)
- 条件:
countDown == 0且isSending == true(倒计时归零但未重发) - 动作:设置
verifyStatus为"expired";切换动态面板到State3;显示对应文案。
用例2:校验失败
- 条件:
inputCode != verifyCode(注意是!=,不是==,避免空值误判) - 动作:设置
verifyStatus为"fail";errorCount变量加1(用于后续防刷);切换动态面板到State3。
用例3:校验成功
- 条件:
inputCode == verifyCode且countDown > 0(输入正确且未过期) - 动作:设置
verifyStatus为"success";切换动态面板到State3;跳转到下一个页面(如登录成功页)。
这里有个精妙设计:用inputCode != verifyCode作为失败条件,而不是!(inputCode == verifyCode)。因为当inputCode为空时,"" == verifyCode为假,"" != verifyCode为真,直接进入失败分支,避免空输入被当成“正确”处理。这是从某金融类Demo里学到的教训——当时没加这层判断,测试同学输空格就过了校验,差点酿成合规事故。
4.3 刷新验证码功能:如何实现“点击图标重新生成”?
刷新功能常被简化为“重新执行获取验证码逻辑”,但真实场景中,它必须考虑状态一致性。比如:倒计时进行到30秒时点击刷新,应该立即停止当前倒计时,重置为60秒,而不是叠加两个倒计时。
实现步骤:
- 在State3的“失败”和“过期”状态下,添加一个刷新图标(可用Font Awesome图标库);
- 选中该图标 → “交互”→“新建交互”→“单击时”;
- 用例条件:无(直接执行);
- 动作序列:
- 设置
isSending为true; - 设置
countDown为60; - 重新生成
verifyCode(同获取验证码逻辑); - 设置
verifyStatus为"idle"(清除上次校验状态); - 切换动态面板到State2(进入倒计时态);
- 聚焦输入框。
- 设置
关键点:必须重置verifyStatus为"idle"。否则,如果上次是"fail",刷新后verifyStatus还是"fail",State3会一直显示失败文案。我最初漏了这步,客户预览时疯狂点击刷新图标,界面卡在红色提示上不动,以为是原型坏了,尴尬到想删库跑路。
5. 常见问题与排查技巧实录:那些只有踩过才懂的坑
5.1 倒计时卡在60秒不动?检查这3个致命点
这是新手最高频问题,表面看是倒计时没走,根源往往在逻辑链断裂。按优先级排查:
动态面板“载入时”事件是否绑定到正确元件?
错误做法:把“载入时”事件绑在按钮上。正确做法:必须绑定在动态面板本身。因为按钮点击只触发一次,而倒计时需要持续循环,只有面板载入才能反复触发。条件中的变量名是否拼写错误?
比如把[[countDown]]写成[[countdown]],Axure会静默忽略该条件,不报错也不执行。打开预览模式,点击“变量监视器”,手动点几次按钮,看countDown值是否变化。不变就是变量名错了。“等待”动作是否被放在了错误位置?
如果“等待1000毫秒”放在“设置变量”之前,第一次执行时countDown还是60,等待1秒后才减到59,导致显示延迟。必须确保“设置变量”在前,“等待”在后。
排查技巧:在“载入时”用例里,临时加一条“显示提示”动作,内容为
[[countDown]]。预览时如果提示框一直显示60,说明条件没触发;如果提示框一闪而过显示59,说明逻辑通了,只是UI没更新——这时检查动态面板状态切换是否正确。
5.2 输入正确却提示“验证码错误”?字符编码陷阱揭秘
某次帮某高校做教务系统原型,测试同学反馈:“明明输入了图片上的4827,却总提示错误”。查了半小时,发现是Axure生成的随机数用了Math.random(),但图片显示用的是中文全角数字(如“4827”),而输入框接收的是英文半角(“4827”),两者Unicode码不同,比对永远为假。
解决方案:
- 生成验证码时强制用半角数字:
[[Math.floor(Math.random()*10000)+1000]](+1000确保4位,避免出现123变成0123); - 或更稳妥:用字符串拼接:
[[Math.floor(Math.random()*10)]]+[[Math.floor(Math.random()*10)]]+[[Math.floor(Math.random()*10)]]+[[Math.floor(Math.random()*10)]]。
另外,输入框属性要设为“文本”而非“密码”。虽然验证码常被当作密码处理,但Axure的“密码”类型会自动屏蔽部分字符,导致inputCode取不到值。这点在官方文档里都没提,是我用排除法试出来的。
5.3 多个验证码区域互相干扰?变量作用域避坑指南
大型项目常有多个验证码模块(如注册页、找回密码页、二次验证页)。如果全用全局变量,A页的countDown会影响B页的倒计时。解决方案有两个:
方案1:用页面级变量(推荐)
Axure 10支持“页面变量”,在页面右键→“页面变量”→新建。每个页面的变量相互隔离,page1.countDown和page2.countDown互不影响。设置动作时,变量名写成[[page1.countDown]]即可。方案2:变量名加前缀(兼容老版本)
比如注册页用reg_countDown,找回页用reset_countDown。虽然麻烦,但在Axure 8/9中是唯一解。
我建议新项目直接上方案1,老项目维护用方案2。去年迁移一个Axure 8的老系统,硬是把27个验证码模块的变量名全加了前缀,改了3小时,但换来的是后期零冲突。
5.4 预览时倒计时飞快?浏览器兼容性真相
有同事反馈:“在Chrome预览正常,Edge里倒计时1秒变10秒”。查证发现是Edge对Axure生成的JS执行优化过度,导致“等待1000毫秒”被压缩。解决方案很简单:把等待时间从1000改为1050毫秒。多出的50毫秒抵消浏览器优化,实测在Chrome/Firefox/Edge/Safari四端误差均小于0.2秒。
最后分享一个小技巧:做完所有交互后,不要急着交稿。用手机扫码预览,在微信里打开,点几次“获取验证码”,观察倒计时是否平滑、输入框是否聚焦、错误提示是否及时。移动端的触控延迟、网络波动会暴露PC端看不到的问题。我有个习惯:所有验证码原型,必须在真机上完成3轮全流程测试,才算真正过关。