表单构建Skill building-forms

本技能提供系统化的表单构建指导,涵盖输入组件选择、验证策略、可访问性合规(WCAG 2.1)、UX最佳实践,以及JavaScript/React和Python的示例实现。适用于创建各种表单界面,如注册流程、调查问卷、多步向导等。关键词:表单构建、输入模式、验证、可访问性、WCAG 2.1、React、Python、前端开发、用户体验。

前端开发 0 次安装 0 次浏览 更新于 3/23/2026

name: 构建表单 description: 构建表单组件和数据收集界面,包括联系表单、注册流程、结账过程、调查问卷和设置页面。包含50多种输入类型、验证策略、可访问性模式(WCAG 2.1)、多步向导和UX最佳实践。提供从数据类型到组件选择的决策树、验证时机指导和错误处理模式。在创建表单、收集用户输入、构建调查、实施验证、设计多步工作流或确保表单可访问性时使用。

表单系统与输入模式

构建可访问、用户友好的表单,包含系统化的组件选择、验证策略和UX最佳实践。

目的

表单是Web应用程序中用户数据输入的主要机制。本技能提供系统化指导,用于:

  • 根据数据需求选择适当的输入类型
  • 实现增强用户体验的验证策略
  • 确保WCAG 2.1 AA可访问性合规
  • 创建复杂模式(多步向导、条件字段、动态表单)

何时使用此技能

触发条件:

  • 构建联系表单、登录/注册流程、结账过程
  • 实施调查、问卷或设置页面
  • 添加用户输入的验证
  • 创建多步工作流或向导
  • 确保表单可访问性
  • 收集结构化数据(地址、信用卡、日期)

常见请求:

  • “创建带有验证的注册表单”
  • “构建多步结账流程”
  • “为电子邮件输入添加内联验证”
  • “使此表单适用于屏幕阅读器”
  • “实施带有条件问题的调查”

通用表单概念

组件选择框架

黄金规则: 数据类型 → 输入组件 → 验证模式

首先确定要收集的数据类型,然后选择适当的组件:

快速参考:

  • 短文本(<100字符)→ 文本输入、电子邮件输入、密码输入
  • 长文本(>100字符)→ 文本区域、富文本编辑器、代码编辑器
  • 数字 → 数字输入、货币输入、滑块
  • 日期/时间 → 日期选择器、时间选择器、日期范围选择器
  • 布尔值 → 复选框、切换开关
  • 单选 → 单选按钮组(2-7选项)、下拉选择(>7选项)、自动完成(>15选项)
  • 多选 → 复选框组、多选、标签输入
  • 文件/媒体 → 文件上传、图片上传
  • 结构化 → 地址输入、信用卡输入、电话号码输入

详细决策树: 参见 references/decision-tree.md

验证时机策略

推荐默认: 失焦时验证,配合渐进增强

字段原始(从未触摸过):无验证
用户输入时:不显示错误
失焦时(字段失去焦点):验证并显示错误
首次错误后:切换到变更时验证
修复后:立即显示成功

验证模式:

  1. 提交时 - 表单提交时验证(简单表单)
  2. 失焦时 - 字段失去焦点时验证(推荐用于大多数表单)
  3. 变更时 - 用户输入时验证(密码强度、可用性检查)
  4. 防抖 - 用户停止输入后验证(基于API的验证)
  5. 渐进 - 从失焦时开始,首次错误后切换到变更时

完整验证指南: 参见 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):

  1. 渐进披露 - 初始仅显示必需字段,按需显示高级选项
  2. 智能默认值 - 预填已知信息,基于上下文建议值
  3. 内联验证与积极反馈 - 有效输入时显示绿色勾选标记,提供有用的错误消息
  4. 移动优先 - 大触摸目标(最小44像素),适当的键盘类型
  5. 减少认知负荷 - 分组相关字段,使用清晰标签,提供示例
  6. 错误预防 - 约束防止无效输入,自动补全减少拼写错误
  7. 自动保存和恢复 - 自动保存草稿状态,丢失数据前警告

详细UX模式: 参见 references/ux-patterns.md

错误消息最佳实践

良好错误消息公式:

  1. 什么错了 - “电子邮件地址无效”
  2. 为什么重要 - “我们需要这个来发送您的收据”
  3. 如何修复 - “格式:name@example.com”

示例:

差: “无效输入” ✅ 好: “电子邮件地址必须包含@符号(例如,name@example.com)”

差: “错误” ✅ 好: “密码必须至少8个字符长”

差: “字段必填” ✅ 好: “请输入您的电子邮件地址,以便我们发送订单确认”

语气指南:

  • 对话式,非机器人化
  • 有帮助,非指责性
  • 具体,非通用
  • 可操作,非仅描述性

语言特定实现

本技能提供上述通用表单概念,以及以下语言特定实现。

JavaScript/React(主要)

推荐技术栈:

  • React Hook Form - 表单状态管理(最佳性能,8KB包)
  • Zod - TypeScript优先的模式验证
  • Radix UIReact 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的WTForms
  • references/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

最佳实践总结

  1. 从语义HTML开始 - 尽可能使用原生 <input>, <select>, <textarea>
  2. 标签所有内容 - 每个输入都需要可见、描述性的标签
  3. 失焦时验证 - 大多数表单的最佳UX平衡
  4. 提供有用的错误 - 解释错误并告知如何修复
  5. 支持键盘导航 - Tab顺序、箭头键、Esc关闭
  6. 移动优先 - 大触摸目标、适当的键盘
  7. 渐进披露 - 不要一开始就显示所有字段
  8. 尽可能自动保存 - 防止数据丢失
  9. 用屏幕阅读器测试 - 确保ARIA属性正常工作
  10. 使用设计令牌 - 一致的样式、主题支持

附加资源

  • 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实现指南