代码演示
如何引入
<script lang="ts">
import { Button, PinCode, TypographyText } from '@fibrae/semi-ui-svelte';
</script>
基本使用
代码
<script lang="ts">
import { PinCode } from '@fibrae/semi-ui-svelte';
const onComplete = (value: string) => console.log('pincode: ', value);
const onChange = (value: string) => console.log(value);
</script>
<div>
<PinCode aria-label="Verification code, small" {onChange} {onComplete} size="small" value="123456" />
<br />
<PinCode aria-label="Verification code, default" {onChange} {onComplete} size="default" value="123456" />
<br />
<PinCode aria-label="Verification code, large" {onChange} {onComplete} size="large" value="123456" />
</div>受控
使用 bind:value 绑定验证码字符串;只传 value 时作为初始内容,没有 defaultValue
代码
<script lang="ts">
import { Button, PinCode } from '@fibrae/semi-ui-svelte';
let value = $state('69af41');
const setRandomValue = () => {
value = String(Math.floor(Math.random() * 100000000)).slice(0, 6);
};
const onComplete = (code: string) => console.log('pincode: ', code);
const onChange = (code: string) => console.log(code);
</script>
<div>
<Button onclick={setRandomValue}>Set Random Value</Button>
<br />
<br />
<PinCode aria-label="Verification code" bind:value format="mixed" {onChange} {onComplete} />
</div>限制验证码格式
设置位数
通过 count 设置位数,默认 6 位,下方 Demo 设置为 4 位
代码
<script lang="ts">
import { PinCode } from '@fibrae/semi-ui-svelte';
const onComplete = (value: string) => console.log('pincode: ', value);
const onChange = (value: string) => console.log(value);
</script>
<PinCode aria-label="Verification code" count={4} {onChange} {onComplete} size="large" value="6688" />设置字符范围
使用 format 控制可输入的字符范围
- 传入 "number" 只允许设置数字
- 传入 "mixed" 允许数字和字母
- 传入正则表达式,只允许输入可通过正则判定的字符
- 传入函数,验证码会在输入的时候以字符为单位被依次作为参数分别单独传入进行校验,当函数返回 true 时,允许该字符被输入进 PinCode
纯数字
字母和数字
只大写字母
只小写字母(函数判断)
字母和数字
只大写字母
只小写字母(函数判断)
代码
<script lang="ts">
import { PinCode, TypographyText } from '@fibrae/semi-ui-svelte';
const onComplete = (value: string) => console.log('pincode: ', value);
const isLower = (char: string) => /[a-z]/.test(char);
</script>
<div>
<TypographyText id="pincode-format-number">纯数字</TypographyText>
<PinCode aria-labelledby="pincode-format-number" format="number" {onComplete} />
<br />
<TypographyText id="pincode-format-mixed">字母和数字</TypographyText>
<PinCode aria-labelledby="pincode-format-mixed" format="mixed" {onComplete} />
<br />
<TypographyText id="pincode-format-upper">只大写字母</TypographyText>
<PinCode aria-labelledby="pincode-format-upper" format={/[A-Z]/} {onComplete} />
<br />
<TypographyText id="pincode-format-lower">只小写字母(函数判断)</TypographyText>
<PinCode aria-labelledby="pincode-format-lower" format={isLower} {onComplete} />
</div>手动聚焦失焦
用 bind:this 取得组件实例,调用方法 focus(index) 与 blur(index),入参为对应 Input 的序号,序号从 0 开始
代码
<script lang="ts">
import { Button, PinCode } from '@fibrae/semi-ui-svelte';
let value = $state('69af41');
let pinCode = $state<ReturnType<typeof PinCode>>();
const onComplete = (code: string) => console.log('pincode: ', code);
const onChange = (code: string) => console.log(code);
</script>
<div>
<Button onclick={() => pinCode?.focus(2)}>Focus Third Input</Button>
<br />
<br />
<PinCode aria-label="Verification code" bind:this={pinCode} bind:value format="mixed" {onChange} {onComplete} />
</div>API 参考
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| autofocus | 挂载时是否自动聚焦到第一个输入框。只在用户明确进入验证码输入步骤时开启,页面加载时自动聚焦会让读屏跳过之前的内容。 | boolean | false |
| count | 验证码位数。 | number | 6 |
| disabled | 是否禁用。 | boolean | - |
| format | 单个字符的格式限制:number 只允许数字,mixed 允许数字和字母,正则或函数按字符判定。 | PinCodeFormat | "number" |
| onBlur | 焦点离开整个验证码时的回调。 | Type(event: FocusEvent) => void | - |
| onChange | 内容变化时的回调,参数为当前内容。 | Type(value: string) => void | - |
| onComplete | 所有位数输入完毕时的回调,参数为当前内容。 | Type(value: string) => void | - |
| onFocus | 焦点进入整个验证码时的回调,在输入框之间移动不触发。 | Type(event: FocusEvent) => void | - |
| size | 输入框大小,可选 large、default、small。 | InputSize | - |
| validateStatus | 校验状态,传给每个输入框;error 时显示错误样式。 | ValidateStatus | - |
| value | 输入框内容,可用 bind:value 双向绑定。bind:value={get, set} 时完全受控;只传 value 时作为初值。 | string | - |
Methods
| 方法 | 说明 | 类型 |
|---|---|---|
| blur | 让第 index 个输入框失焦,序号从 0 开始,超出范围时忽略。 | Type(index: number) => void |
| focus | 聚焦第 index 个输入框,序号从 0 开始,超出范围时忽略;光标放在该格字符之后。 | Type(index: number) => void |
class、style(字符串)、aria-label、aria-labelledby、data-* 落在 role="group" 的根元素上。id 落在第一个输入框上,<label for> 指向第一格。aria-describedby、aria-errormessage、aria-invalid、aria-required、tabindex 落在每个输入框上。name、insetLabel、insetLabelId 被丢弃。onFocus、onBlur 按整组计。autofocus 挂载时聚焦第一个输入框,默认 false,只在用户明确进入验证码输入步骤时开启。
Accessibility
ARIA
- 根元素为
role="group",名称通过aria-label或aria-labelledby提供;没有可见标签时请传aria-label,否则分组没有名称。 - 每格输入框的可访问名称来自语言包,形如「第 1 位,共 6 位」,随
count与格子序号变化,无需手动设置。 aria-describedby、aria-errormessage、aria-invalid、aria-required落在每个输入框上;validateStatus传给每个输入框。format为"number"时输入框使用数字软键盘(inputmode="numeric"),其余为文本键盘。
键盘和焦点
- 每个格子是独立的输入框,输入一个合法字符后焦点移到下一格,在最后一格输入后失焦;已填内容总是从第一格起连续,在空格子之后输入的字符落在第一个空格子上。
Tab与Shift+Tab在格子之间切换。 左箭头、右箭头在格子之间移动焦点;Backspace与Delete都删除当前格字符,后面的字符依次前移,Backspace还会把焦点移到上一格。- 粘贴整段验证码时,从当前格起按字符依次填入各格,遇到不合法字符即停止。
autoFocus(Vue 为autofocus)只在用户明确进入验证码输入步骤时开启,页面加载时自动聚焦会让读屏跳过之前的内容。