news 2026/9/13 8:54:56

amis InputVerificationCode 验证码输入组件详解:属性、事件与源码实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
amis InputVerificationCode 验证码输入组件详解:属性、事件与源码实现

amis InputVerificationCode 验证码输入组件详解:属性、事件与源码实现

【免费下载链接】amis前端低代码框架,通过 JSON 配置就能生成各种页面。项目地址: https://gitcode.com/GitHub_Trending/am/amis

本篇技术文章以 amis 低代码框架的验证码输入组件input-verification-code(InputVerificationCode)为核心,完整覆盖其基本用法、密码模式、自定义分隔符、禁用/只读状态等全部官方配置项与事件机制,并深入 amis 渲染层(packages/amis)与 UI 层(packages/amis-ui)的源码实现,帮助你在 JSON Schema 中快速集成多格验证码输入,理解其焦点自动迁移、粘贴填充、单字符截断等交互细节背后的触发逻辑。

组件定位与注册方式

input-verification-code是 amis 表单体系中的一类表单项控件(FormItem),用于渲染一组并排的独立输入框(默认 6 格),典型场景包括短信验证码、登录口令、交易密码等。它支持通过粘贴一次性填充多个输入框(这是官方文档特别强调的能力)。

从源码结构看,该组件分为两层:

  • amis 渲染层:InputVerificationCode.tsx 通过@FormItem({type: 'input-verification-code'})装饰器注册(见该文件 L98-L103),负责事件派发(dispatchEvent)、数据绑定,并把 Schema 中的字符串分隔符表达式转译成函数;
  • amis-ui 基础组件层:VerificationCode.tsx 中的VerificationCodeComponent提供实际的输入框渲染、焦点管理、粘贴处理等交互逻辑。

在极简构建中,该组件被声明为动态加载,注册于 minimal.ts(getComponent: () => import('./renderers/Form/InputVerificationCode'));而在完整构建中,其 Schema 类型在 SchemaFull.ts 中声明为'input-verification-code': AMISInputTextSchema

基本用法

在表单 Schema 中声明type: "input-verification-code"并指定name,即可得到默认 6 格的验证码输入。以下示例继承自官方文档:

{ "type": "form", "api": "/api/mock2/form/saveForm", "debug": true, "body": [ { "type": "input-verification-code", "name": "verificationCode" } ] }

不指定length时,源码中defaultLength = 6(VerificationCode.tsx),即渲染 6 个输入框;每格只接受一个字符,输入框之间的间距、边框、聚焦态均由 CSS 变量控制(后文样式小节详述)。

密码模式

指定masked = true可开启密码模式,所有输入框将以type="password"渲染,字符显示为掩码,适合输入敏感口令。

{ "type": "form", "api": "/api/mock2/form/saveForm", "debug": true, "body": [ { "type": "input-verification-code", "name": "verificationCode", "masked": true } ] }

在 VerificationCode.tsx 中可以看到,masked直接决定输入框类型:

type={masked ? 'password' : 'text'}

需要注意:密码模式下输入框宽度依然固定,掩码点的大小由浏览器决定,实际效果建议以真机预览为准。

自定义分隔符

指定separator可以自定义每个输入框之后渲染的分隔符。该属性支持 amis 表达式,且表达式中可以访问两个变量:

  • index:当前分隔符所在位置(即它位于第几个输入框之后,从 0 开始);
  • character:该输入框当前填写的字符。

官方文档给出的示例为 9 位验证码,用表达式在特定位置插入-

{ "type": "form", "api": "/api/mock2/form/saveForm", "debug": true, "body": [ { "type": "input-verification-code", "name": "verificationCode", "length": 9, "separator": "${((index + 1) % 3 || index > 7) ? null : '-'}" } ] }

分隔符表达式的实现链路值得注意:

  1. amis 渲染层在 InputVerificationCode.tsx 的render()中,若separator是字符串,就将其包装为(data: {index, character}) => resolveVariableAndFilter(separator, data),即通过 amis 的模板解析引擎求值;若表达式结果为空(如null),该位置不渲染任何内容;
  2. 求值后的函数在 UI 层被逐个输入框调用:VerificationCode.tsx 中{separator?.({index, character: v!})}v即该格当前的字符值。

因此分隔符可以做静态文本(如'-'),也可以根据填写内容动态变化(如未填写时渲染占位提示)。

状态控制:禁用与只读

  • 指定disabled = true可开启禁用模式,输入框整体不可交互,并叠加is-disabled类名呈现禁用样式;
  • 指定readOnly = true可开启只读模式,此时源码中会直接摘除onClickonPasteonKeyDownonChange等交互回调(VerificationCode.tsx 中均以!readOnly ? handler : undefined条件挂载),只保留值展示。
{ "type": "form", "api": "/api/mock2/form/saveForm", "debug": true, "body": [ { "type": "input-verification-code", "name": "verificationCodeDisabled", "value": "123456", "disabled": true }, { "type": "input-verification-code", "name": "verificationCodeReadOnly", "value": "987654", "readOnly": true } ] }

属性表

当做表单项使用时,除了支持 普通表单项属性表 中的配置以外,还支持以下专属配置:

属性名类型默认值说明
lengthnumber6验证码的长度,根据长度渲染对应个数的输入框
maskedbooleanfalse是否是密码模式
separatorstring-分隔符,支持表达式;表达式只可以访问indexcharacter变量,参考自定义分隔符示例

结合 InputVerificationCode.tsx 中定义的VerificationCodeSchema接口,还可直接使用value(初始值/回填值)、disabledreadOnly等属性;length的容错逻辑在 useVerificationCode 中实现:当length非法(非正数)时回退到默认值 6。

事件表

当前组件会对外派发以下事件,可以通过onEvent来监听:

事件名称事件参数说明
finish-输入框都被填充后触发的回调
change-输入值改变时触发的回调

finish:全部填充完成

所有输入框被填满(当前值长度等于length)时触发。可以尝试通过${event.data.value}获取填写的数据:

{ "type": "input-verification-code", "onEvent": { "finish": { "actions": [ { "actionType": "toast", "args": { "msgType": "info", "msg": "${event.data.value}" } } ] } } }

change:输入值改变

每次有效输入(含粘贴、退格)导致值变化时触发,同样可通过${event.data.value}获取当前值:

{ "type": "input-verification-code", "onEvent": { "change": { "actions": [ { "actionType": "toast", "args": { "msgType": "info", "msg": "${event.data.value}" } } ] } } }

从 InputVerificationCode.tsx 的源码可以看到两个事件的派发细节:

  • onFinish通过dispatchEvent('finish', {...data, value}, this)派发,事件参数中除表单作用域数据外额外携带value字段;
  • onChange先派发change事件,若监听者未阻止该事件rendererEvent?.prevented为假),才调用onChange?.(value)把值同步到表单数据。也就是说,onEvent中可以通过preventDefault类机制拦截值更新——这是 amis 事件体系的标准行为。

源码实现:交互行为是怎么来的

amis-ui 的 useVerificationCode Hook 封装了全部核心交互,可以据此准确预判组件行为:

1. 每格单字符onChange处理函数中char.replace(indexVal, '').split('').pop() || ''(L231-L237)意味着每格只保留新输入内容中的最后一个字符,多字符输入会自动截断。

2. 自动焦点迁移。每次filledValue变化后,useEffect会调用focusFirstEmptyInput()(L152-L175):只要当前焦点在验证码输入框组内,就自动把焦点移到第一个空格;当所有格填满时还会主动让最后一个输入框blur()失焦,避免焦点残留在已完成的输入组上。

3. 粘贴填充handlePaste(L189-L198)拦截粘贴事件,取剪贴板文本按字符拆分,从当前格开始向后填充:filledValue.slice(0, index).concat(text.split('')).join('')。这解释了官方文档开头强调的"可通过粘贴完成填充数据"——粘贴 6 位数字即可一次性填满 6 格。

4. 退格逻辑onKeyDown中(L215-L229):若后一格仍有值则阻止退格(先把后一格清空);退格前会做边界修正(空格退格时回退到上一格),保证删除顺序符合直觉。

5. 触发时机tryUpdateValue(L177-L187)中:值变化时先调用props.onChange,随后当newVal.length === length时调用props.onFinish——即finish是"恰好填满"的一次性触发点,change则是每一次有效变更的触发点。

6. 受控/非受控合并。Hook 通过useMergeValue(L104-L132)合并外部value与内部状态:外部传入value时以外部为准(受控),未传入时内部状态自持(非受控),这解释了"状态"示例中直接用value: "123456"回填静态值即可生效的原因。

样式与主题定制

组件整体布局由 _verificationCode.scss 定义:容器为display: flex,单格输入框宽px2rem(35px)(适配移动端 rem 缩放),列间距 4px;边框、圆角、内边距、字号、聚焦阴影、禁用态背景等全部取自--Form-input-*CSS 变量(如--Form-input-borderColor--Form-input-onFocused-borderColor--Form-input-onDisabled-bg)。

这意味着你可以按 amis 的主题体系统一定制验证码输入框外观——覆盖对应的--Form-input-*变量即可改变其边框、聚焦与禁用样式,而无需为验证码组件单独写样式;禁用态通过is-disabled类名切换光标与背景。

小结

input-verification-code是 amis 表单中面向验证码场景的专用控件:length控制格数(默认 6)、masked切换密码掩码、separator以表达式实现位置级动态分隔符、disabled/readOnly控制状态;事件侧以finish(填满)与change(变更)构成完整的反馈闭环。配合 amis 通用的onEventname数据绑定机制,可以在纯 JSON Schema 中完成从验证码采集到提交的全流程,无需手写任何 React 代码。

【免费下载链接】amis前端低代码框架,通过 JSON 配置就能生成各种页面。项目地址: https://gitcode.com/GitHub_Trending/am/amis

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 8:53:20

二阶锥松弛在微电网最优潮流计算中的应用与Matlab实现

1. 项目背景与核心价值微电网作为分布式电源接入配电网的重要载体,其灵活性调节能力直接影响着配电网运行的经济性和安全性。传统配电网最优潮流(OPF)计算在考虑分布式电源时,常因非凸非线性特性导致求解困难。二阶锥松弛&#xf…

作者头像 李华
网站建设 2026/9/13 8:49:21

三道经典测试题,快速分辨GPT-4与GPT-3.5套壳接口

告诉你个尴尬事。前阵子有个朋友找我,说他们团队买了一家第三方AI接口,宣传清清楚楚写着“GPT-4”,结果做出来的产品在复杂逻辑问答上一塌糊涂,用户投诉不断。我让他把接口的返回参数亮出来,结果model字段里赫然写着“…

作者头像 李华
网站建设 2026/9/13 8:48:47

GitHub到Gitea仓库迁移实战:含批量脚本与踩坑避坑指南

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

作者头像 李华
网站建设 2026/9/13 8:48:01

如何用 LeRobot 在 MetaWorld MT50 基准上评估策略?

如何用 LeRobot 在 MetaWorld MT50 基准上评估策略? 【免费下载链接】lerobot 🤗 LeRobot: Making AI for Robotics more accessible with end-to-end learning 项目地址: https://gitcode.com/GitHub_Trending/le/lerobot 你手上已经有一个训练好…

作者头像 李华