name: 构建表单 description: 构建表单组件和数据收集界面,包括联系表单、注册流程、结账过程、调查问卷和设置页面。包含50多种输入类型、验证策略、可访问性模式(WCAG 2.1)、多步向导和UX最佳实践。提供从数据类型到组件选择的决策树、验证时机指导和错误处理模式。在创建表单、收集用户输入、构建调查、实施验证、设计多步工作流或确保表单可访问性时使用。
表单系统与输入模式
构建可访问、用户友好的表单,包含系统化的组件选择、验证策略和UX最佳实践。
目的
表单是Web应用程序中用户数据输入的主要机制。本技能提供系统化指导,用于:
- 根据数据需求选择适当的输入类型
- 实现增强用户体验的验证策略
- 确保WCAG 2.1 AA可访问性合规
- 创建复杂模式(多步向导、条件字段、动态表单)
何时使用此技能
触发条件:
- 构建联系表单、登录/注册流程、结账过程
- 实施调查、问卷或设置页面
- 添加用户输入的验证
- 创建多步工作流或向导
- 确保表单可访问性
- 收集结构化数据(地址、信用卡、日期)
常见请求:
- “创建带有验证的注册表单”
- “构建多步结账流程”
- “为电子邮件输入添加内联验证”
- “使此表单适用于屏幕阅读器”
- “实施带有条件问题的调查”
通用表单概念
组件选择框架
黄金规则: 数据类型 → 输入组件 → 验证模式
首先确定要收集的数据类型,然后选择适当的组件:
快速参考:
- 短文本(<100字符)→ 文本输入、电子邮件输入、密码输入
- 长文本(>100字符)→ 文本区域、富文本编辑器、代码编辑器
- 数字 → 数字输入、货币输入、滑块
- 日期/时间 → 日期选择器、时间选择器、日期范围选择器
- 布尔值 → 复选框、切换开关
- 单选 → 单选按钮组(2-7选项)、下拉选择(>7选项)、自动完成(>15选项)
- 多选 → 复选框组、多选、标签输入
- 文件/媒体 → 文件上传、图片上传
- 结构化 → 地址输入、信用卡输入、电话号码输入
详细决策树: 参见 references/decision-tree.md
验证时机策略
推荐默认: 失焦时验证,配合渐进增强
字段原始(从未触摸过):无验证
用户输入时:不显示错误
失焦时(字段失去焦点):验证并显示错误
首次错误后:切换到变更时验证
修复后:立即显示成功
验证模式:
- 提交时 - 表单提交时验证(简单表单)
- 失焦时 - 字段失去焦点时验证(推荐用于大多数表单)
- 变更时 - 用户输入时验证(密码强度、可用性检查)
- 防抖 - 用户停止输入后验证(基于API的验证)
- 渐进 - 从失焦时开始,首次错误后切换到变更时
完整验证指南: 参见 references/validation-concepts.md
可访问性要求(WCAG 2.1 AA)
关键可访问性模式:
标签和说明:
- 每个输入必须有关联的
<label>或aria-label - 标签必须可见且描述性
- 必填字段明确指示(不只依赖颜色)
- 绝不使用占位符文本作为标签替换
- 为复杂输入提供帮助文本
键盘导航:
- 逻辑、顺序的Tab顺序
- 所有输入键盘可访问
- 自定义组件支持箭头键
- Esc键关闭模态/弹出窗口
- 焦点可见(轮廓或自定义指示器)
错误处理:
- 错误以编程方式与输入关联(
aria-describedby) - 错误消息清晰且可操作
- 错误由屏幕阅读器宣布(
aria-live) - 提交时焦点移动到第一个错误
- 错误不只通过颜色传达
ARIA属性:
aria-required="true"用于必填字段aria-invalid="true"当验证失败时aria-describedby链接到帮助/错误文本role="group"用于相关输入aria-live="polite"用于验证消息
完整可访问性清单: 参见 references/accessibility-forms.md
UX最佳实践
现代表单UX原则(2024-2025):
- 渐进披露 - 初始仅显示必需字段,按需显示高级选项
- 智能默认值 - 预填已知信息,基于上下文建议值
- 内联验证与积极反馈 - 有效输入时显示绿色勾选标记,提供有用的错误消息
- 移动优先 - 大触摸目标(最小44像素),适当的键盘类型
- 减少认知负荷 - 分组相关字段,使用清晰标签,提供示例
- 错误预防 - 约束防止无效输入,自动补全减少拼写错误
- 自动保存和恢复 - 自动保存草稿状态,丢失数据前警告
详细UX模式: 参见 references/ux-patterns.md
错误消息最佳实践
良好错误消息公式:
- 什么错了 - “电子邮件地址无效”
- 为什么重要 - “我们需要这个来发送您的收据”
- 如何修复 - “格式:name@example.com”
示例:
❌ 差: “无效输入” ✅ 好: “电子邮件地址必须包含@符号(例如,name@example.com)”
❌ 差: “错误” ✅ 好: “密码必须至少8个字符长”
❌ 差: “字段必填” ✅ 好: “请输入您的电子邮件地址,以便我们发送订单确认”
语气指南:
- 对话式,非机器人化
- 有帮助,非指责性
- 具体,非通用
- 可操作,非仅描述性
语言特定实现
本技能提供上述通用表单概念,以及以下语言特定实现。
JavaScript/React(主要)
推荐技术栈:
- React Hook Form - 表单状态管理(最佳性能,8KB包)
- Zod - TypeScript优先的模式验证
- Radix UI 或 React Aria - 可访问组件基元
快速开始:
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import * as z from 'zod';
// 定义验证模式
const schema = z.object({
email: z.string().email('无效电子邮件地址'),
password: z.string().min(8, '密码必须至少8个字符'),
});
type FormData = z.infer<typeof schema>;
function LoginForm() {
const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
resolver: zodResolver(schema),
mode: 'onBlur', // 失焦时验证(推荐)
});
const onSubmit = (data: FormData) => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<label htmlFor="email">电子邮件</label>
<input id="email" {...register('email')} type="email" />
{errors.email && <span role="alert">{errors.email.message}</span>}
<label htmlFor="password">密码</label>
<input id="password" {...register('password')} type="password" />
{errors.password && <span role="alert">{errors.password.message}</span>}
<button type="submit">登录</button>
</form>
);
}
详细JavaScript/React文档:
references/javascript/react-hook-form.md- 完整React Hook Form指南references/javascript/zod-validation.md- Zod模式验证模式references/javascript/examples/- 工作代码示例
Python(主要)
推荐技术栈:
- Pydantic - 数据验证和设置管理(运行时验证,类型安全)
- FastAPI - 现代异步Web框架,带自动验证
- WTForms - Flask/Django表单处理(使用传统框架时)
快速开始(FastAPI + Pydantic):
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, EmailStr, Field, validator
app = FastAPI()
# 定义验证模式
class LoginForm(BaseModel):
email: EmailStr # 验证电子邮件格式
password: str = Field(..., min_length=8, description="密码必须至少8个字符")
@validator('password')
def validate_password_strength(cls, v):
if not any(char.isdigit() for char in v):
raise ValueError('密码必须包含至少一个数字')
if not any(char.isupper() for char in v):
raise ValueError('密码必须包含至少一个大写字母')
return v
@app.post("/api/login")
async def login(form_data: LoginForm):
# Pydantic自动验证传入数据
# 如果验证失败,返回422和错误详情
return {"message": "登录成功", "email": form_data.email}
# 示例错误响应(自动):
# {
# "detail": [
# {
# "loc": ["body", "email"],
# "msg": "值不是有效的电子邮件地址",
# "type": "value_error.email"
# }
# ]
# }
详细Python文档:
references/python/pydantic-forms.md- Pydantic验证模式references/python/wtforms.md- Flask/Django的WTFormsreferences/python/examples/- 工作代码示例
Rust(未来)
计划库:
- validator - 结构字段验证
- Leptos / Yew - 响应式Web框架
Rust实现将在需要时添加。
Go(未来)
计划库:
- Templ - 类型安全HTML模板
- html/template - 标准库模板
Go实现将在需要时添加。
组件层级
层级1:基础输入组件
文本型:
- 文本字段(单行)
- 文本区域(多行)
- 电子邮件输入(带验证)
- 密码输入(带可见性切换)
- 数字输入(带步进控制)
- 电话输入(带格式化)
- URL输入(带协议验证)
- 搜索输入(带清除按钮)
选择:
- 单选按钮组(2-7选项)
- 复选框(布尔值或多个)
- 切换开关(清晰的开关状态)
- 下拉选择(多选项)
- 多选(多选)
日期和时间:
- 日期选择器(日历界面)
- 时间选择器(小时/分钟)
- 日期范围选择器(开始和结束)
- 日期时间选择器(组合)
层级2:丰富输入组件
高级选择:
- 自动完成/组合框(输入过滤)
- 标签输入(多标签)
- 传输列表(在列表间移动项目)
- 列表框(键盘可导航)
专用:
- 颜色选择器(十六进制、RGB、HSL)
- 文件上传器(单、多、拖放)
- 图片上传器(裁剪、调整大小、预览)
- 滑块/范围(单或范围)
- 评分输入(星号、数字、表情符号)
- 富文本编辑器(格式化、媒体)
- 代码编辑器(语法高亮)
- Markdown编辑器(预览、工具栏)
结构化数据:
- 地址输入(多字段)
- 信用卡输入(格式化)
- 电话号码(国际化)
- 货币输入(符号、小数)
层级3:复杂表单模式
多步表单:
- 线性向导(步骤1 → 2 → 3)
- 分支向导(条件步骤)
- 进度指示器
- 保存和恢复(草稿状态)
- 审查和提交页面
动态表单:
- 条件字段(显示/隐藏)
- 重复部分(添加/移除)
- 字段数组(动态列表)
- 嵌套表单(复杂对象)
高级模式:
- 内联编辑(点击编辑)
- 批量编辑(多记录)
- 自动保存(定期或变更时)
- 乐观更新
- 撤销/重做功能
与设计令牌集成
所有表单组件使用design-tokens技能进行视觉样式,支持主题切换(亮/暗/高对比度/自定义品牌)。
关键令牌类别:
- 颜色 - 输入背景、边框、文本、错误/成功状态
- 间距 - 填充、字段间间隙、标签边距
- 排版 - 字体大小、输入、标签、错误的权重
- 边框 - 边框宽度、半径、焦点环
- 阴影 - 焦点指示器、高程
参见: skills/design-tokens/ 获取完整主题文档。
常见用例
联系表单
// 带有验证的基础联系表单
// 参见:references/javascript/examples/basic-form.tsx
注册流程
// 带密码强度的多步注册
// 参见:references/javascript/examples/multi-step-wizard.tsx
内联验证
// 带防抖的实时验证
// 参见:references/javascript/examples/inline-validation.tsx
带有条件逻辑的调查
// 带有条件字段的动态表单
// 参见:references/javascript/examples/conditional-form.tsx
设置页面
// 混合输入类型带自动保存
// 参见:references/javascript/examples/settings-form.tsx
快速决策指南
问题:我应该使用什么输入?
→ 参见 references/decision-tree.md 获取完整决策树
问题:我应该在什么时候验证?
→ 使用失焦时验证配合渐进增强(首次错误后切换到变更时)
→ 参见 references/validation-concepts.md 获取所有策略
问题:如何使我的表单可访问?
→ 使用语义HTML,标签所有输入,支持键盘导航
→ 参见 references/accessibility-forms.md 获取WCAG 2.1清单
问题:如何处理复杂验证?
→ 使用模式验证(Zod用于TypeScript,Yup用于JavaScript)
→ 参见 references/javascript/zod-validation.md 获取模式
问题:如何构建多步表单?
→ 使用状态管理配合进度跟踪
→ 参见 references/javascript/examples/multi-step-wizard.tsx
最佳实践总结
- 从语义HTML开始 - 尽可能使用原生
<input>,<select>,<textarea> - 标签所有内容 - 每个输入都需要可见、描述性的标签
- 失焦时验证 - 大多数表单的最佳UX平衡
- 提供有用的错误 - 解释错误并告知如何修复
- 支持键盘导航 - Tab顺序、箭头键、Esc关闭
- 移动优先 - 大触摸目标、适当的键盘
- 渐进披露 - 不要一开始就显示所有字段
- 尽可能自动保存 - 防止数据丢失
- 用屏幕阅读器测试 - 确保ARIA属性正常工作
- 使用设计令牌 - 一致的样式、主题支持
附加资源
references/decision-tree.md- 完整组件选择框架references/validation-concepts.md- 所有验证策略和模式references/accessibility-forms.md- WCAG 2.1 AA合规清单references/ux-patterns.md- 现代表单UX最佳实践references/javascript/- JavaScript/React实现指南