PinInput 验证码
分格验证码输入:字符约束过滤(type / pattern)、分隔符分组、尺寸与形态档位、OTP 短信自动填充、填满自动提交、loading / success 校验反馈;键盘方向键移动、Backspace 回退、粘贴自动分发(含过滤)。
基础用法
默认 6 位
默认 type="number"(仅数字),适合绝大多数验证码场景。
自定义长度
length=4
通过 length 设置格子数量。
字符约束(type 语义化)
number(默认)/ alphanumeric / text
type 是语义化的字符约束档(不再透传原生 input type):
number(默认):仅数字[0-9],联动inputmode="numeric"(移动端弹数字键盘)alphanumeric:字母 + 数字text:任意字符
内部格子恒为原生 text 输入并逐字符过滤——旧版 type="number" 透传原生时可以输入 e / E / + / - / .(原生 number input 的合法语法),该缺陷已修复。约束对逐位键入、粘贴分发、受控 value 初值三者一致生效;非法字符静默拒绝(通行做法)。设 mask 时格子切换为 password 遮罩。非法 type 值回落 number 并 console.warn(同值去重)。
自定义正则(pattern)
pattern=[0-3](仅 0–3 数字)
pattern 接收正则字符串,按逐字符匹配(如 [0-3] 限制 0–3、[a-m] 限制前半段字母);设置后覆盖 type 的内置字符集(inputmode 仍随 type)。非法正则字符串告警后回落 type 约束。
分隔符(separator)
3+4 手机验证码分组
每相邻对之间(separator-after 缺省)
separator 为分隔内容(字符串),separator-after 为 1 起始的格位索引列表(逗号分隔,如 "3" = 第 3 格后、"2,5" = 第 2、5 格后);缺省时在每相邻对之间插入。分隔元素带 part="separator" 可定制样式,aria-hidden 对读屏不可见,不参与取值。
尺寸(size)
small / medium / large
size 三档对齐全局控件高度 token(small=24px / medium=32px 默认 / large=40px),格子宽度与字号随档位缩放;非法值回落 medium 并告警。
占位符(placeholder)
placeholder 透传各格
placeholder 显示在每个空格内(惯例用单字符,如 ○)。
形态(variant)与连体(attached)
outlined(默认)/ filled / underlined
attached 连体(共享边框)
variant 形态档:outlined 描边(默认)/ filled 填充 / underlined 下划线;attached 去除格间距并合并相邻边框(仅端点圆角,聚焦格盖于邻格之上)。非法 variant 回落 outlined 并告警。样式全部走逻辑属性,dir="rtl" 下自动镜像。
遮罩(mask)
mask
mask 将格子切换为密码型(平台原生圆点观感),输入值被遮罩。
OTP 短信自动填充(otp)
otp
otp 布尔属性为各格设置 autocomplete="one-time-code",移动端(iOS / Android)会在键盘上方弹出系统短信验证码建议,点按自动填入。
自动聚焦与焦点方法(autofocus / focus / blur)
autofocus + focus(index) / blur()
设置 autofocus 属性后,首次连接即聚焦首个空格;focus(index?) 聚焦指定格(缺省首个空格,全部填满时聚焦末格,越界回落默认策略),blur() 使当前活动格失焦。组件级进出派发 oas-focus / oas-blur(携带格 index),格间移动不重复派发。
Vue 提示:
autofocus是 HTMLElement 反射属性,模板里裸写会被 Vue 走 property 赋值剥掉,需用:autofocus="true"绑定形态(经属性反射生效)。
填满自动提交(auto-submit)
auto-submit(显式 opt-in)
auto-submit 布尔属性在验证码填满时自动调用关联 form(最近 form 祖先)的 requestSubmit()——触发 submit 事件与原生约束校验(非绕过),无关联 form 时安全 no-op。OTP「填满即校验」流程无需中间按钮。
校验反馈(loading / success / aria-invalid)
输入正确码 1234 走完整流程:填满 → loading(格子锁定 + spinner)→ success 成功态;其他码 → 错误态 1.6s 后自动清空重试。
loading → success / error
aria-invalid 手动切换
aria-invalid 静态示例
loading:提交中态——格子禁用、容器aria-busy="true"、覆盖层 spinner,输入与键盘全部锁定success:成功态——格子描--oas-color-success绿边(聚焦环同步变色)aria-invalid:校验失败态——格子与容器同步该状态并标 danger 边框(已列入 observedAttributes,动态setAttribute即时生效);error 优先于 success(两者同设时按错误呈现)
受控初值(value)
value 预填
value 分发到各格;超出 length 的部分自动截断,不符合当前 type / pattern 约束的字符在展示层同步滤除。内部输入会写回 value 属性(非受控通道),宿主外部改动即时同步且不重建格子引用。
禁用 / 只读
disabled
readonly
事件
依次体验:点入格子(oas-focus)→ 逐位输入(oas-input)→ 填满(oas-complete)→ 点击页面空白处失焦(oas-change + oas-blur)。
input / complete / change / focus / blur
三事件正交、互不重叠:
| 事件 | 时机 | detail |
|---|---|---|
oas-input | 每格输入(实时) | { value, index } |
oas-complete | 验证码填满(回退重填再次派发) | { value } |
oas-change | 失焦提交:组件失焦且值相对获焦时有变化 | { value } |
oas-focus / oas-blur | 焦点进入 / 离开组件(格间移动不派发) | { index } |
RTL
dir=rtl
dir="rtl" 下格子自右向左排布,方向键语义反转(ArrowLeft 前进、ArrowRight 后退),分隔符位置随视觉序镜像。
迁移说明(破坏性变更)
oas-change 事件语义变更(对齐表单族 change 惯例,与 oas-complete 解除重复):
- 旧版:
oas-change与oas-complete在填满时同时双发,语义完全重复 - 新版:
oas-input(逐位输入)/oas-complete(填满)/oas-change(失焦提交)三事件正交 - 迁移指引:
- 旧监听
oas-change做实时校验 / 输入联动 → 改监听oas-input - 旧监听
oas-change做填满即校验 → 改监听oas-complete(如需自动提交配合auto-submit) - 需要失焦确认最终值(表单 commit 语义)→ 继续监听
oas-change
- 旧监听
type 属性语义化:
- 旧版:
type透传原生 input type(如tel),且默认text可输任意字符;type="number"下原生允许e/E/+/-/. - 新版:
type为语义档number(默认)/text/alphanumeric,内部恒原生text+ 逐字符过滤;非法值(含旧版tel等原生类型)回落number并告警 - 未显式设置
type的存量用法从「任意字符」变为「仅数字」——需要任意字符请显式type="text"
API
oas-pin-input
属性
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
aria-invalid | 校验失败态(同步到容器与各格,标 danger) | string | — |
attached | 连体形态:格间无间距共享边框,仅端点圆角 | boolean | — |
auto-submit | 填满自动提交(找最近 form 调 requestSubmit;无 form 时 no-op) | boolean | — |
autofocus | 首次连接聚焦首个空格 | boolean | — |
disabled | 禁用 | boolean | — |
length | 验证码位数 | string | 6 |
loading | 提交中:格禁用 + aria-busy + spinner 遮罩,键盘输入全锁 | boolean | — |
mask | 星号遮罩 | boolean | — |
otp | OTP 语义:内层格 autocomplete="one-time-code"(拉起系统短信验证码自动填充) | boolean | — |
pattern | 逐字符正则约束(覆盖 type 过滤;非法正则告警回落) | string | — |
placeholder | 空格占位符 | string | — |
readonly | 只读 | boolean | — |
separator | 分隔符内容(配合 separator-after) | string | — |
separator-after | 在第 N 格后插入分隔符(1 起始索引,逗号分隔多个,如 3,7;缺省每相邻格之间) | string | — |
size | 尺寸档位 small / medium(默认)/ large | string | medium |
success | 成功态绿边框(error 优先) | — | — |
type | 格子输入类型 | string | number |
value | 当前值(受控) | string | — |
variant | 形态:outlined(默认)/ filled / underlined | string | outlined |
Property(JS property;是否写回 attribute 见各行说明)
| Property | 说明 | 类型 | 默认值 |
|---|---|---|---|
value | 当前值:各格字符拼接字符串;property 与 value 属性同源(setter 写回 attribute、属性改动即时同步各格),会反射到 attribute | string | — |
事件
| 事件 | 说明 |
|---|---|
oas-blur | 焦点离开组件时派发,detail: { index } |
oas-change | 失焦提交:组件失焦且值相对获焦快照变化时派发,detail: { value } |
oas-complete | 填满时派发,detail: { value } |
oas-focus | 焦点进入组件时派发(格间移动不派发),detail: { index } |
oas-input | 每格输入,detail: { value, index } |
键盘:←/→ 格间移动,Backspace 删除当前格并回退,支持粘贴自动分发;全空时每格均可聚焦(原生 caret)。
ARIA:容器 role="group" + aria-label,每格 aria-label="第 n 位",aria-invalid 同步到容器与各格。