Form
表单组件族,与 @tanstack/react-form 完全集成,提供类型安全的表单字段组件。
导入
tsx
import { Form } from '@xcloud/ui-core'
import { useForm } from '@tanstack/react-form'示例
基础用法
tsx
import { useForm } from '@tanstack/react-form';
import { Form } from '@xcloud/ui-core';
interface LoginFormData {
email: string;
password: string;
remember: boolean;
}
export function LoginForm() {
const form = useForm<LoginFormData>({
defaultValues: {
email: '',
password: '',
remember: false,
},
onSubmit: async ({ value }) => {
console.log(value);
},
});
return (
<form onSubmit={(e) => { e.preventDefault(); form.handleSubmit(); }}>
<Form.FormField.Root<LoginFormData>
form={form}
name="email"
label="邮箱地址"
type="email"
required
/>
<Form.FormField.Root<LoginFormData>
form={form}
name="password"
label="密码"
type="password"
required
/>
<Form.FormSwitchField.Root<LoginFormData>
form={form}
name="remember"
label="记住我"
/>
<button type="submit">登录</button>
</form>
);
}可用组件
FormField
文本输入字段
tsx
<Form.FormField.Root<TFormData>
form={form}
name="fieldName"
label="标签"
hint="提示信息"
type="text"
placeholder="占位符"
icon={IconComponent}
required
disabled
/>FormTextareaField
多行文本输入
tsx
<Form.FormTextareaField.Root<TFormData>
form={form}
name="fieldName"
label="标签"
rows={4}
maxLength={200}
/>FormSelectField
下拉选择框
tsx
<Form.FormSelectField.Root<TFormData>
form={form}
name="fieldName"
label="选择一个选项"
placeholder="请选择"
options={[
{ value: 'option1', label: '选项 1' },
{ value: 'option2', label: '选项 2', disabled: true },
]}
/>FormRadioField
单选按钮组
tsx
<Form.FormRadioField.Root<TFormData>
form={form}
name="fieldName"
label="选择一个选项"
options={[
{ value: 'option1', label: '选项 1' },
{ value: 'option2', label: '选项 2' },
]}
/>FormCheckboxField
复选框
tsx
<Form.FormCheckboxField.Root<TFormData>
form={form}
name="fieldName"
label="我同意服务条款"
/>FormSwitchField
开关
tsx
<Form.FormSwitchField.Root<TFormData>
form={form}
name="fieldName"
label="启用此选项"
hint="开启后将..."
/>FormSegmentedControlField
分段控制器
tsx
<Form.FormSegmentedControlField.Root<TFormData>
form={form}
name="fieldName"
label="选择模式"
options={[
{ value: 'light', label: '浅色' },
{ value: 'dark', label: '深色' },
{ value: 'auto', label: '自动' },
]}
/>FormDigitField
验证码输入
tsx
<Form.FormDigitField.Root<TFormData>
form={form}
name="verificationCode"
label="验证码"
numInputs={6}
/>FormCustomField
自定义字段渲染
tsx
<Form.FormCustomField.Root<TFormData>
form={form}
name="customField"
>
{(field) => (
<div>
<label>自定义字段</label>
<MyCustomInput
value={field.state.value}
onChange={(value) => field.handleChange(value)}
onBlur={field.handleBlur}
/>
{field.state.meta.errors.length > 0 && (
<span className="text-red-500">
{field.state.meta.errors[0]}
</span>
)}
</div>
)}
</Form.FormCustomField.Root>类型安全
所有 Form 组件都支持泛型类型参数,提供完整的类型提示:
tsx
// ✅ 字段名自动完成
<Form.FormField.Root<LoginFormData>
form={form}
name="email" // TypeScript 会提示: "email" | "password" | "remember"
/>
// ❌ TypeScript 会报错
<Form.FormField.Root<LoginFormData>
form={form}
name="username" // 错误:'username' 不存在于 LoginFormData
/>Field API
在 FormCustomField 中,field 对象提供以下属性和方法:
field.state.value- 当前字段值field.state.meta.errors- 验证错误数组field.state.meta.isTouched- 字段是否被触摸过field.state.meta.isDirty- 字段值是否被修改过field.handleChange(value)- 更新字段值field.handleBlur()- 处理失焦事件
更多 API 请参考 @tanstack/react-form 文档
最佳实践
- 总是定义表单数据类型
tsx
// ✅ 好
interface MyFormData { ... }
const form = useForm<MyFormData>({ ... });
// ❌ 不好
const form = useForm({ ... }); // 失去类型安全- 使用泛型指定表单类型
tsx
// ✅ 好 - 获得字段名自动完成
<Form.FormField.Root<MyFormData> form={form} name="..." />
// ⚠️ 可以工作,但失去自动完成
<Form.FormField.Root form={form} name="..." />- 结合验证库使用
tsx
import { zodValidator } from '@tanstack/zod-form-adapter';
import { z } from 'zod';
const schema = z.object({
email: z.string().email(),
password: z.string().min(8),
});
const form = useForm({
validatorAdapter: zodValidator,
validators: {
onChange: schema,
},
});