You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
4.7 KiB
4.7 KiB
统一Form组件使用指南
概述
统一Form组件基于 react-hook-form + zod 验证,提供了一套完整的表单解决方案,包括:
- 类型安全的表单验证
- 统一的UI样式
- 丰富的表单控件
- 错误处理和状态管理
基础用法
1. 定义Schema
// schemas/example.ts
import { z } from 'zod';
import { formValidations } from '@/lib/form-utils';
export const exampleSchema = z.object({
name: formValidations.name(50),
email: formValidations.email(),
description: formValidations.optional(formValidations.text(0, 200)),
color: z.string().min(1, '请选择颜色'),
});
export type ExampleFormData = z.infer<typeof exampleSchema>;
2. 使用Form组件
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { Form } from '@/components/ui/form';
import { FormInput, FormTextarea, FormColorPicker } from '@/components/ui/form-controls';
import { exampleSchema, type ExampleFormData } from '@/schemas/example';
import { defaultColorOptions, createFormSubmitHandler } from '@/lib/form-utils';
function ExampleForm() {
const form = useForm<ExampleFormData>({
resolver: zodResolver(exampleSchema),
defaultValues: {
name: '',
email: '',
description: '',
color: '#3B82F6',
},
});
const submitHandler = createFormSubmitHandler<ExampleFormData>(
async (data) => {
// 处理表单提交
console.log('提交数据:', data);
},
{
onError: (error) => {
console.error('提交失败:', error);
}
}
);
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(submitHandler)} className="space-y-4">
<FormInput
control={form.control}
name="name"
label="名称"
placeholder="请输入名称"
required
/>
<FormInput
control={form.control}
name="email"
label="邮箱"
type="email"
placeholder="请输入邮箱"
required
/>
<FormTextarea
control={form.control}
name="description"
label="描述"
placeholder="请输入描述"
rows={3}
/>
<FormColorPicker
control={form.control}
name="color"
label="颜色"
colors={defaultColorOptions}
/>
<Button type="submit" disabled={form.formState.isSubmitting}>
{form.formState.isSubmitting ? '提交中...' : '提交'}
</Button>
</form>
</Form>
);
}
可用的表单控件
FormInput
文本输入框,支持多种类型:
type: 'text' | 'email' | 'password' | 'number'
FormTextarea
多行文本框:
rows: 行数,默认3行
FormSelect
下拉选择框:
options: SelectOption[] 选项数组
FormColorPicker
颜色选择器:
colors: ColorOption[] 颜色选项数组
FormInfo
只读信息显示:
label: 标签value: 显示值description: 可选描述
验证规则
使用 formValidations 工具函数:
import { formValidations } from '@/lib/form-utils';
const schema = z.object({
// 必填字段
required: formValidations.required('此字段必填'),
// 文本长度限制
text: formValidations.text(0, 100, '内容'),
// 名称验证(文件夹/项目名)
name: formValidations.name(50),
// 邮箱验证
email: formValidations.email(),
// 密码验证
password: formValidations.password(8),
// URL验证
url: formValidations.url(),
// 数字验证
number: formValidations.number(0, 100),
// 可选字段
optional: formValidations.optional(formValidations.text(0, 200)),
});
表单提交处理
使用 createFormSubmitHandler 创建提交处理器:
const submitHandler = createFormSubmitHandler<FormData>(
async (data) => {
// API调用
await api.create(data);
},
{
onSuccess: (data) => {
// 成功回调
console.log('创建成功:', data);
},
onError: (error) => {
// 错误处理
console.error('创建失败:', error);
},
}
);
最佳实践
- Schema定义: 将表单Schema定义在独立的文件中,便于复用和维护
- 类型安全: 使用TypeScript类型推断,确保类型安全
- 错误处理: 统一使用
createFormSubmitHandler处理表单提交 - 验证规则: 优先使用
formValidations中的预定义规则 - 默认值: 总是为表单字段提供合理的默认值
- 禁用状态: 在提交过程中禁用表单控件,防止重复提交
示例项目
参考 CreateFolderModal 组件的实现,了解完整的使用方式。