Skyroc UI
输入

Form

类型安全的表单状态管理与验证系统

表单(Form)提供完整的表单状态管理、字段验证、动态数组和计算字段能力。基于 @skyroc/form 核心库封装,通过 FormField 组件将表单字段与 UI 布局(标签、描述、错误提示)整合,同时提供丰富的 Hooks 用于程序化控制表单。

import {
  Form,
  FormField,
  FormComputedField,
  FormList,
  useForm,
  useWatch,
  useSelector,
  useFieldState,
  useFieldError,
  useArrayField,
  useEffectField,
  useUndoRedo
} from '@skyroc/web-ui';

架构说明

Form 系统分为三层:

  • 核心层@skyroc/form):纯逻辑的表单状态管理,包含 FormFieldComputedFieldList 四个原语组件以及完整的 Hooks 体系。
  • UI 层FormFieldFormComputedField):将核心层的 Field / ComputedField 与布局组件(Label、Description、Message)组合,提供开箱即用的表单字段 UI。
  • 配置层(ConfigProvider):通过全局配置为 FormField 提供默认 sizeclassNames 等属性。

用户可直接使用 UI 层的 FormField 获得完整的表单字段体验,也可使用核心层的 Field 自定义布局。

何时使用

  • 需要收集和验证用户输入时(登录、注册、设置等表单)。
  • 表单字段之间存在联动关系(计算字段、条件显隐)。
  • 需要动态增删表单项(动态列表、可编辑表格)。
  • 需要程序化控制表单(外部按钮提交、跨组件读写表单值)。
  • 需要撤销/重做能力的编辑场景。

基础用法

Form 包裹表单内容,FormField 渲染带标签和验证的字段。通过 name 绑定字段路径,rules 定义验证规则。

Preview
Code
Loading...
<Form
  initialValues={{ email: '', password: '' }}
  onFinish={(values) => console.log('提交:', values)}
  onFinishFailed={(error) => console.log('验证失败:', error)}
>
  <FormField
    name="email"
    label="邮箱"
    rules={[{ required: true, message: '请输入邮箱' }, { type: 'email', message: '邮箱格式不正确' }]}
    component={Input}
  />
  <FormField
    name="password"
    label="密码"
    rules={[{ required: true }, { minLength: 6, message: '至少 6 个字符' }]}
    component={Input}
  />
  <button type="submit">提交</button>
</Form>

默认值表单

通过 initialValues 设置表单默认值,description 为字段添加描述文本。

Preview
Code
Loading...

受控表单(useForm)

通过 useForm 创建表单实例,实现程序化读写、填充和重置。

Preview
Code
Loading...
const [form] = useForm();

form.setFieldsValue({ name: 'John', email: 'john@example.com' });
form.setFieldValue('name', 'Updated Name');
form.getFieldsValue();       // 获取全部值
form.getFieldValue('name');  // 获取单个字段值
form.resetFields();          // 重置全部
form.resetFields(['name']);  // 重置指定字段

字段验证

支持 requiredtypeminLengthmaxLengthpattern 等内置规则,也支持 validateField / validateFields 局部验证。

Preview
Code
Loading...

警告验证(warningOnly)

warningOnly 规则验证失败仅显示警告,不阻止表单提交。

Preview
Code
Loading...

自定义验证消息

通过 validateMessages 自定义验证错误消息模板,支持 ${label}${min} 等占位符。

Preview
Code
Loading...

Schema 验证(Zod)

支持 Standard Schema(如 Zod、Valibot 等)进行声明式验证,无需在每个字段上单独设置 rules

Preview
Code
Loading...
import { z } from 'zod';

const schema = z.object({
  username: z.string().min(3, '至少 3 个字符'),
  age: z.number().min(18, '须年满 18 岁')
});

<Form schema={schema} onFinish={(values) => console.log(values)}>
  <FormField name="username" label="用户名" component={Input} />
  <FormField name="age" label="年龄" component={Input} />
  <button type="submit">提交</button>
</Form>

异步验证

自定义异步验证器,模拟服务端唯一性检查等场景。

Preview
Code
Loading...

计算字段

FormComputedField 根据其他字段自动计算值,渲染为只读字段。

Preview
Code
Loading...
<Form initialValues={{ price: 0, quantity: 1, total: 0 }}>
  <FormField name="price" label="单价" component={Input} />
  <FormField name="quantity" label="数量" component={Input} />
  <FormComputedField
    name="total"
    label="总价"
    deps={['price', 'quantity']}
    compute={(get) => (get('price') || 0) * (get('quantity') || 0)}
    component={Input}
  />
</Form>

动态列表

FormList 管理动态数组字段,提供 insert、remove、move、swap、replace 操作。

Preview
Code
Loading...
<Form initialValues={{ users: [{ name: '', email: '' }] }}>
  <FormList name="users">
    {(fields, { insert, remove }) => (
      <>
        {fields.map((field, index) => (
          <div key={field.key}>
            <FormField name={`${field.name}.name`} label="姓名" component={Input} />
            <FormField name={`${field.name}.email`} label="邮箱" component={Input} />
            <button type="button" onClick={() => remove(index)}>删除</button>
          </div>
        ))}
        <button type="button" onClick={() => insert(fields.length, { name: '', email: '' })}>
          添加用户
        </button>
      </>
    )}
  </FormList>
</Form>

字段变更监听(useEffectField)

useEffectField 创建响应式副作用,当指定字段变化时触发。不写回表单值,仅用于副作用。

Preview
Code
Loading...
useEffectField(['country'], (get) => {
  const country = get('country');
  console.log('国家变更为:', country);
});

useWatch

监听表单字段值变化,支持单个字段、多个字段或全部字段。

Preview
Code
Loading...
const username = useWatch('username', { form });
const { name, email } = useWatch(['name', 'email'], { form });
const allValues = useWatch(form);
const allValues = useWatch(); // 使用 context 中的 form

useSelector

从表单状态中派生计算值,仅在计算结果变化时触发重渲染。

Preview
Code
Loading...
const total = useSelector(
  (get) => (get('price') || 0) * (get('quantity') || 0),
  { deps: ['price', 'quantity'] }
);

重置表单

resetFields 支持全部重置或按字段名局部重置。

Preview
Code
Loading...

销毁时清除(clearOnDestroy)

clearOnDestroy 控制表单销毁时是否清除数据。

Preview
Code
Loading...

字段保留(preserve)

preserve 控制字段卸载后是否保留值。设为 true 时,隐藏的字段值仍保留在表单中。

Preview
Code
Loading...

中间件

通过 form.use() 注册中间件,拦截表单 action 实现日志、权限检查等自定义逻辑。

Preview
Code
Loading...
const loggingMiddleware = ({ getState }) => (next) => (action) => {
  console.log('Before:', action.type, getState());
  const result = next(action);
  console.log('After:', getState());
  return result;
};

form.use(loggingMiddleware);

撤销/重做(useUndoRedo)

useUndoRedo 为表单添加撤销/重做能力,追踪字段值变更和数组操作。

Preview
Code
Loading...
const { canUndo, canRedo, undo, redo } = useUndoRedo(form);

API

Form

表单容器,提供表单状态管理上下文。支持多态渲染:默认渲染为 <form> 元素,可通过 component 自定义或设为 false 实现无包裹渲染。

属性说明类型默认值
initialValues表单初始值DeepPartial<Values>-
form外部表单实例,通过 useForm 创建FormInstance-
schema表单验证 Schema(支持 Zod、Valibot 等 Standard Schema)FormSchema-
component渲染的容器元素,设为 false 则不渲染包裹元素ElementType | false'form'
validateTrigger字段验证的默认触发时机string | string[]'onChange'
validateMessages自定义验证错误消息模板ValidateMessages-
preserve卸载时是否保留字段值booleantrue
clearOnDestroy销毁时是否清除表单数据boolean-
onFinish表单提交且验证通过后的回调(values: Values) => void-
onFinishFailed表单提交但验证失败时的回调(errorInfo: ValidateErrorEntity) => void-
onValuesChange表单值变化时的回调(changedValues: Partial<Values>, values: Values) => void-
onFieldsChange字段元数据变化时的回调(changedFields: Meta[], allFields: Meta[]) => void-

FormField

带完整 UI 布局的表单字段组件,自动渲染标签、描述文本和错误提示。

属性说明类型默认值
name*字段路径,支持嵌套路径如 "user.name"string-
label字段标签ReactNode-
description字段描述文本,显示在输入框下方string-
component渲染为表单输入的组件(如 Input、Select、Textarea)ElementTypeField
rules字段验证规则数组Rule[]-
initialValue字段初始值any-
trigger触发值变更的事件名string'onChange'
validateTrigger触发验证的事件名string | string[] | false-
valuePropName传递字段值的 prop 名称string'value'
getValueFromEvent从事件参数中提取值的函数(...args: any[]) => any-
normalize值变更后的标准化函数(value: any, prevValue: any, allValues: Values) => any-
preserve卸载时是否保留字段值booleantrue
size尺寸,影响字段布局的字号与间距'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl''md'
classNames各 slot 的自定义 classFormClassNames-
className字段容器的 classClassValue-

FormComputedField

计算字段,根据其他字段自动计算值并以只读状态渲染。

属性说明类型默认值
name*字段路径string-
deps*依赖的字段路径数组,这些字段变化时会触发重新计算string[]-
compute*计算函数,接收 get 函数和所有表单值,返回计算结果(get: (name: string) => any, all: Values) => any-
label字段标签ReactNode-
description字段描述文本string-
rules验证规则(计算字段也可验证)Rule[]-
size尺寸'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl''md'
classNames各 slot 的自定义 classFormClassNames-

FormList

动态数组字段,通过 render prop 渲染数组项并提供数组操作方法。

属性说明类型默认值
name*数组字段路径string-
children*渲染函数,接收 fields 数组和操作方法对象(fields: ListRenderItem[], ops: ListOperations) => ReactNode-
initialValue数组初始值any[]-
preserve卸载时是否保留字段值booleantrue

FormInstance

通过 useForm() 创建的表单实例,提供以下方法:

值操作

方法签名说明
getFieldValue(name) => value获取指定字段的值
getFieldsValue(names?) => values获取多个字段值,不传参时返回全部
setFieldValue(name, value) => void设置指定字段的值
setFieldsValue(values) => void批量设置多个字段的值
setDisabled(name, disabled) => void设置字段禁用状态
setHidden(name, hidden) => void设置字段隐藏状态

状态查询

方法签名说明
getField(name) => Meta获取字段完整元数据
getFields(names?) => MetaShape获取多个字段的元数据
getFieldError(name) => string[]获取字段错误信息
getFieldsError(names?) => Record获取多个字段的错误信息
getFieldTouched(name) => boolean字段是否被触碰过
getFieldValidating(name) => boolean字段是否正在验证
getFormState() => FormState获取完整表单状态快照
isDisabled(name) => boolean字段是否禁用
isHidden(name) => boolean字段是否隐藏

操作

方法签名说明
validateField(name, opts?) => Promise<boolean>验证指定字段
validateFields(names?, opts?) => Promise<boolean>验证多个字段
resetFields(names?) => void重置字段到初始值
submit() => void触发表单提交
use(middleware) => void添加中间件

类型

FormClassNames

表单字段各 slot 的自定义 class。

字段类型说明
itemClassValue字段容器的 class。
labelClassValue标签的 class。
descriptionClassValue描述文本的 class。
messageClassValue错误消息的 class。

Rule

验证规则配置。支持内置类型验证、自定义验证器和异步验证。

字段类型说明
requiredboolean是否必填。
typeRuleType内置类型验证器。
messagestring自定义错误消息。
minnumber | Date | string最小值(数值类型)或最早日期。
maxnumber | Date | string最大值(数值类型)或最晚日期。
minLengthnumber字符串最小长度。
maxLengthnumber字符串最大长度。
lennumber精确长度或精确数值。
patternRegExp正则表达式匹配。
enumany[]type 为 enum 时的允许值列表。
whitespaceboolean是否禁止纯空白字符串。
validator(rule: Rule, value: any, values: any) => Promise<string | any> | string | undefined自定义验证函数,返回字符串表示错误。
warningOnlyboolean为 true 时验证失败仅产生警告,不阻止提交。
validateTriggerstring | string[]指定触发此规则的事件。
transform(value: any) => any验证前转换值的函数。
skipIfEmptyboolean非必填字段为空时是否跳过检查(默认 true)。
debounceMsnumber异步验证器的防抖时间(毫秒)。

Meta

字段元数据,包含字段的完整状态信息。

字段类型说明
valueany当前字段值。
errorsstring[]验证错误消息数组。
warningsstring[]验证警告消息数组。
touchedboolean字段是否被用户交互过。
validatedboolean字段是否已完成验证。
validatingboolean字段是否正在验证中。
namestring字段路径。

ValidateErrorEntity

表单提交验证失败时的错误信息。

字段类型说明
errorCountnumber存在错误的字段数量。
errorFieldsMeta[]存在错误的字段元数据数组。
errorMapRecord<string, string[]>字段名到错误消息的映射。
firstErrorNamestring第一个错误字段的名称(用于自动聚焦)。
valuesValues验证失败时的表单值。
warningMapRecord<string, string[]>字段名到警告消息的映射。
submittedAtnumber验证失败的时间戳。

ListRenderItem

FormList render prop 中的数组项数据。

字段类型说明
keystring稳定的 React key,用于列表渲染优化。
namestring数组项的字段路径(如 "users.0")。

ListOperations

FormList 提供的数组操作方法。

字段类型说明
insert(index: number, item: any) => void在指定位置插入项。
remove(index: number) => void删除指定位置的项。
move(from: number, to: number) => void将项从一个位置移动到另一个位置。
swap(i: number, j: number) => void交换两个位置的项。
replace(index: number, item: any) => void替换指定位置的项。

RuleType

内置验证类型

'string' | 'number' | 'integer' | 'float' | 'boolean' | 'date' | 'email' | 'url' | 'hex' | 'regexp' | 'enum'

FormSchema

表单验证 Schema 类型,支持 Standard Schema V1(如 Zod、Valibot)或自定义验证函数

StandardSchema | ((state: values, name?: string | string[]) => Promise<{ message: string; path: string[] }[]>)

ValidateMessages

自定义验证消息模板,支持占位符 ${min}、${max}、${len}、${label}、${value}。各验证类型均可自定义消息。

{ required?: string; whitespace?: string; default?: string; string?: { min?: string; max?: string; len?: string; pattern?: string }; number?: { min?: string; max?: string; len?: string }; ... }

FormInstance

表单实例,由 useForm() 创建,提供完整的值操作、状态查询和操作方法。详见上方 FormInstance 章节。

{ getFieldValue, getFieldsValue, setFieldValue, setFieldsValue, getField, getFieldError, validateField, validateFields, resetFields, submit, use, ... }

ClassValue

CSS 类名类型

string | null | undefined | Record<string, boolean> | ClassValue[]

On this page