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.9 KiB

Form组件使用示例

概述

新的Form组件系统提供了灵活的表单构建方式,支持统一配置和独立控制两种使用模式。

核心组件

  • FormContainer: 提供统一的表单配置
  • FormItem: 灵活的表单项组件
  • FormInfo: 只读信息显示组件

使用方式

1. 统一配置模式

使用FormContainer为所有表单项提供统一配置:

import { FormContainer, FormItem } from "@/components/ui/form";
import { Input, Textarea } from "@/components/ui";

function UnifiedForm() {
  return (
    <FormContainer layout="vertical" spacing="md">
      <FormItem label="用户名" required>
        <Input placeholder="请输入用户名" />
      </FormItem>

      <FormItem label="邮箱" required>
        <Input type="email" placeholder="请输入邮箱" />
      </FormItem>

      <FormItem label="描述">
        <Textarea placeholder="请输入描述" rows={3} />
      </FormItem>
    </FormContainer>
  );
}

2. 独立控制模式

直接使用FormItem,每个表单项独立配置:

import { FormItem } from "@/components/ui/form";
import { Input, Select } from "@/components/ui";

function IndependentForm() {
  return (
    <div className="space-y-4">
      <FormItem
        label="项目名称"
        required
        layout="vertical"
        description="请输入项目的唯一名称"
      >
        <Input placeholder="请输入项目名称" />
      </FormItem>

      <FormItem label="项目类型" layout="horizontal" labelWidth="120px">
        <Select>
          <SelectTrigger>
            <SelectValue placeholder="选择项目类型" />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="web">Web应用</SelectItem>
            <SelectItem value="mobile">移动应用</SelectItem>
          </SelectContent>
        </Select>
      </FormItem>
    </div>
  );
}

3. 混合使用模式

FormContainer中覆盖特定表单项的配置:

import { FormContainer, FormItem } from "@/components/ui/form";

function MixedForm() {
  return (
    <FormContainer layout="vertical" spacing="md" labelWidth="100px">
      {/* 使用统一配置 */}
      <FormItem label="基本信息" required>
        <Input placeholder="请输入基本信息" />
      </FormItem>

      {/* 覆盖布局为水平 */}
      <FormItem label="状态" layout="horizontal" labelWidth="80px">
        <Select>
          <SelectTrigger>
            <SelectValue placeholder="选择状态" />
          </SelectTrigger>
        </Select>
      </FormItem>

      {/* 覆盖为内联布局 */}
      <FormItem label="启用" layout="inline">
        <Switch />
      </FormItem>
    </FormContainer>
  );
}

布局选项

vertical (垂直布局)

  • Label在上,Content在下
  • 适合大多数表单场景
  • 默认布局

horizontal (水平布局)

  • Label在左,Content在右
  • 适合紧凑的表单布局
  • 可设置labelWidth控制标签宽度

inline (内联布局)

  • Label和Content在同一行
  • 适合开关、复选框等简单控件
  • 最紧凑的布局方式

间距选项

  • sm: 小间距 (gap-1)
  • md: 中等间距 (gap-2) - 默认
  • lg: 大间距 (gap-4)

错误处理

<FormItem label="用户名" required error={errors.username?.message}>
  <Input placeholder="请输入用户名" />
</FormItem>

只读信息显示

import { FormInfo } from "@/components/ui/form";

<FormInfo
  label="创建时间"
  value="2024-01-15 10:30:00"
  description="项目的创建时间"
/>;

与react-hook-form集成

import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { FormContainer, FormItem } from "@/components/ui/form";

function ReactHookFormExample() {
  const form = useForm({
    resolver: zodResolver(schema),
    defaultValues: {
      name: "",
      email: "",
    },
  });

  return (
    <form onSubmit={form.handleSubmit(onSubmit)}>
      <FormContainer layout="vertical" spacing="md">
        <FormItem
          label="姓名"
          required
          error={form.formState.errors.name?.message}
        >
          <Input {...form.register("name")} />
        </FormItem>

        <FormItem
          label="邮箱"
          required
          error={form.formState.errors.email?.message}
        >
          <Input type="email" {...form.register("email")} />
        </FormItem>
      </FormContainer>
    </form>
  );
}

最佳实践

  1. 统一风格: 在同一个表单中保持一致的布局和间距
  2. 合理标签宽度: 水平布局时根据标签长度设置合适的labelWidth
  3. 错误处理: 始终为必填字段提供错误信息显示
  4. 描述信息: 为复杂字段提供描述信息帮助用户理解
  5. 响应式设计: 在小屏幕上考虑使用垂直布局

实际案例

参考CreateFolderModal组件的实现,了解完整的使用方式。