第十六章:表单规范
定义表单的状态管理、验证和反馈规范
16.1 表单状态机
整体状态
┌─────────────┐
│ Pristine │ ← 初始状态,未修改
└──────┬──────┘
│ 用户输入
▼
┌─────────────┐
┌──────────────►│ Dirty │ ← 已修改
│ └──────┬──────┘
│ │ 失去焦点或提交
│ ▼
│ ┌─────────────┐
│ 修改 ┌─────│ Validating │ ← 验证中
│ │ └──────┬──────┘
│ │ │
│ │ ┌──────┴──────┐
│ │ ▼ ▼
│ │ ┌───────┐ ┌─────────┐
│ │ │ Valid │ │ Invalid │
│ │ └───┬───┘ └────┬────┘
│ │ │ │
│ │ │ 提交 │ 修改
│ │ ▼ │
│ │ ┌───────────┐ │
│ │ │Submitting │ │
│ │ └─────┬─────┘ │
│ │ │ │
│ │ ┌─────┴─────┐ │
│ │ ▼ ▼ │
│ │ Success Error │
│ │ │ │ │
└─────────┴───┴─────────┴─────┘字段级状态
每个表单字段 MUST 维护以下状态:
| 状态 | 类型 | 说明 |
|---|---|---|
| value | any | 当前值 |
| touched | boolean | 是否被触摸过(获得过焦点) |
| dirty | boolean | 值是否被修改过 |
| validating | boolean | 是否正在验证 |
| errors | string[] | 验证错误列表 |
16.2 验证规范
验证时机
| 时机 | 触发条件 | 适用场景 |
|---|---|---|
| onChange | 值变化时 | 即时反馈的字段 |
| onBlur | 失去焦点时 | 大多数字段的默认行为 |
| onSubmit | 提交时 | 最终校验 |
默认策略:
- 首次验证:onBlur(用户离开字段时)
- 后续验证:onChange(已有错误时即时更新)
- 最终验证:onSubmit(提交前完整校验)
验证类型
同步验证
立即返回结果,用于:
- 必填检查
- 格式检查(邮箱、数字等)
- 长度限制
- 正则匹配
异步验证
需要网络请求,用于:
- 地址格式验证(调用链服务)
- 余额检查
- 重复检查
异步验证规范:
- MUST 显示验证中状态
- MUST 支持防抖(建议 300-500ms)
- MUST 取消过期请求
- SHOULD 验证中禁用提交按钮
16.3 核心表单规范
16.3.1 转账表单
字段定义:
| 字段 | 类型 | 必填 | 验证规则 |
|---|---|---|---|
| toAddress | string | Y | 非空 + 地址格式(异步) |
| amount | string | Y | 非空 + 正数 + 余额检查(异步) |
| memo | string | N | 最大 24 字符 |
状态机:
┌─────────────────────────────────────────────────────────┐
│ TransferForm │
├─────────────────────────────────────────────────────────┤
│ State │
│ ├─ step: 'input' | 'confirm' | 'result' │
│ ├─ toAddress: { value, errors, validating } │
│ ├─ amount: { value, errors, validating } │
│ └─ memo: { value, errors } │
├─────────────────────────────────────────────────────────┤
│ Transitions │
│ ├─ input → confirm : 所有字段 valid │
│ ├─ confirm → input : 用户返回编辑 │
│ ├─ confirm → result : 提交成功或失败 │
│ └─ result → input : 用户重新发起 │
└─────────────────────────────────────────────────────────┘验证流程:
用户输入地址
│
▼
同步验证:非空
│
├─ 失败 → 显示"请输入收款地址"
│
▼
异步验证(500ms 防抖):调用 isValidAddress(address, chainId)
│
├─ 验证中 → 显示加载指示器
│
├─ 失败 → 显示"地址格式不正确"
│
▼
验证通过 → 清除错误16.3.2 创建钱包表单
多步骤流程:
Step 1: 设置钱包锁(图案)
│
▼
Step 2: 展示助记词
│
▼
Step 3: 验证助记词
│
▼
Step 4: 选择区块链网络
│
▼
Complete: 创建成功Step 1 字段:
| 字段 | 验证规则 |
|---|---|
| patternLock | 最少连接 4 个点 |
Step 3 验证:
随机选择 3 个位置,用户输入对应单词:
请输入第 3 个单词:[输入框]
请输入第 7 个单词:[输入框]
请输入第 11 个单词:[输入框]验证规则:输入值 MUST 与对应位置的单词完全匹配
16.3.3 导入钱包表单
字段定义:
| 字段 | 类型 | 验证规则 |
|---|---|---|
| secretInput | string | 非空 |
| secretType | enum | 自动检测:mnemonic / privateKey / arbitrary |
| patternLock | string | 最少连接 4 个点 |
多步骤流程:
Step 1: 输入助记词
│
▼
Step 2: 设置钱包锁(图案)
│
▼
Step 3: 选择区块链网络
│
▼
Complete: 导入成功secretType 检测规则:
输入内容
│
├─ 12/15/18/21/24 个空格分隔的单词 → mnemonic
│
├─ 0x 开头 + 64 个十六进制字符 → privateKey
│
├─ 64 个十六进制字符 → privateKey
│
└─ 其他 → arbitrary(BFM 特殊密钥)BFM 任意密钥说明:
BFM 链支持任意字符串作为密钥,不限于标准助记词格式。
- MUST 使用多行文本输入框
- SHOULD 提示用户这是 BFM 特有功能
16.4 错误反馈规范
错误显示位置
┌─────────────────────────────────┐
│ 标签名 [必填] │
├─────────────────────────────────┤
│ [输入框] │ ← 输入区域
├─────────────────────────────────┤
│ ⚠ 错误信息 │ ← 紧邻输入框下方
└─────────────────────────────────┘错误样式
| 元素 | 正常状态 | 错误状态 |
|---|---|---|
| 输入框边框 | 中性色 | 红色(destructive) |
| 错误文本 | 隐藏 | 红色小字 |
| 标签 | 中性色 | 红色(可选) |
错误信息文案规范
| 类型 | 格式 | 示例 |
|---|---|---|
| 必填 | 请输入 | 请输入收款地址 |
| 格式 | {字段名}格式不正确 | 地址格式不正确 |
| 范围 | {字段名}必须在 X 到 Y 之间 | 金额必须大于 0 |
| 异步 | 余额不足 |
16.5 表单提交规范
提交按钮状态
| 状态 | 条件 | 按钮显示 |
|---|---|---|
| disabled | 有必填字段为空 或 有验证错误 | 禁用态 |
| enabled | 所有字段 valid | 正常态 |
| loading | 正在提交 | 加载态 + "提交中..." |
提交结果处理
成功:
- 显示成功反馈(Toast 或 页面)
- 清空表单 或 导航到结果页
失败:
- 显示错误信息(具体原因)
- 保留表单数据
- 提供重试选项
16.6 表单可访问性
标签关联
- MUST 每个输入框有关联的 label
- MUST 使用 for/id 或嵌套关联
错误通知
- MUST 错误信息通过 aria-describedby 关联到输入框
- SHOULD 使用 aria-live 通知屏幕阅读器
焦点管理
- MUST 验证失败时焦点移至第一个错误字段
- MUST 多步骤表单切换时焦点移至新步骤第一个输入
本章小结
- 表单有完整的状态机定义
- 验证分同步/异步,遵循防抖策略
- 核心表单(转账、创建钱包、导入钱包)有详细规范
- 错误反馈遵循一致的位置和样式规范
- 提交按钮状态与表单状态联动
下一章
继续阅读 第十七章:交互规范。