--- description: "Shadcn-ui 管理页表单开发指令" --- ## 概述 基于 `src/client/admin-shadcn/pages/Users.tsx` 中用户管理表单的实现,提取可复用的表单开发模式和最佳实践,适用于基于 Shadcn-ui 的管理后台表单开发。 ## 核心特性 ### 1. 类型安全表单 - **后端Schema复用**:直接使用后端定义的 Zod Schema - **RPC类型提取**:从 Hono 客户端自动推断类型 - **一致的类型定义**:前后端类型完全同步 ### 2. 表单状态管理(推荐:创建/编辑表单分离模式) - **分离表单实例**:为创建和编辑分别使用独立的表单实例, Form组件也分开 - **类型安全**:创建使用CreateSchema,编辑使用UpdateSchema,避免类型冲突 - **字段差异处理**:创建时的必填字段在编辑时变为可选,敏感字段特殊处理 - **状态隔离**:两种模式的状态完全独立,避免交叉污染 ### 3. 统一的UI组件模式 - **Shadcn-ui组件集成**:使用标准的 Shadcn-ui 表单组件 - **响应式布局**:适配不同屏幕尺寸 - **无障碍支持**:完整的 ARIA 属性支持 ## 开发模板 ### 基础结构模板(创建/编辑分离模式) ```typescript // 1. 类型定义(使用后端真实类型) import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from '@/client/components/ui/form'; import { Input } from '@/client/components/ui/input'; import { Button } from '@/client/components/ui/button'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/client/components/ui/dialog'; // 2. 分离的表单配置 const [isCreateForm, setIsCreateForm] = useState(true); const [editingEntity, setEditingEntity] = useState(null); // 用于存储编辑时的实体数据 // 3. 独立的表单实例 const createForm = useForm({ resolver: zodResolver(CreateEntityDto), // 使用创建专用的Schema defaultValues: { // 创建时必填字段的默认值 }, }); const updateForm = useForm({ resolver: zodResolver(UpdateEntityDto), // 使用更新专用的Schema defaultValues: { // 更新时可选字段的默认值(会被实际数据覆盖) }, }); // 4. 表单切换逻辑(核心模式) const handleCreateEntity = () => { setEditingEntity(null); setIsCreateForm(true); createForm.reset({ // 创建时的初始值(必填字段必须有值) }); setIsModalOpen(true); }; const handleEditEntity = (entity: EntityResponse) => { setEditingEntity(entity); setIsCreateForm(false); updateForm.reset({ ...entity, // 特殊处理:敏感字段在编辑时设为可选 password: undefined, // 密码在更新时可选,不修改则留空 // 其他需要特殊处理的字段 }); setIsModalOpen(true); }; ``` ### 表单字段模板 #### 文本输入框 ```typescript ( 用户名 * )} /> ``` #### 邮箱输入框 ```typescript ( 邮箱 )} /> ``` #### 密码输入框 ```typescript ( 密码 * )} /> ``` #### 开关控件(布尔值) ```typescript (
状态 禁用后用户将无法登录系统
field.onChange(checked ? 1 : 0)} />
)} /> ``` #### 可选字段处理 ```typescript // 创建时:必须提供值 nickname: z.string().optional() // 更新时:完全可选 nickname: z.string().optional() ``` ## 高级表单组件模板 ### 头像选择器集成 ```typescript import AvatarSelector from '@/client/admin-shadcn/components/AvatarSelector'; ( 头像 field.onChange(value)} maxSize={2} uploadPath="/avatars" uploadButtonText="上传头像" previewSize="medium" placeholder="选择头像" /> )} /> ``` ### 下拉选择框 ```typescript import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/client/components/ui/select'; ( 状态 )} /> ``` ### 数字输入框 ```typescript ( 年龄 field.onChange(Number(e.target.value))} /> )} /> ``` ### 日期选择器 ```typescript import { Popover, PopoverContent, PopoverTrigger } from '@/client/components/ui/popover'; import { Calendar } from '@/client/components/ui/calendar'; import { CalendarIcon } from 'lucide-react'; import { cn } from '@/client/lib/utils'; ( 出生日期 date > new Date() || date < new Date("1900-01-01") } initialFocus /> )} /> ``` ### 文本域 ```typescript import { Textarea } from '@/client/components/ui/textarea'; ( 描述