# FormPreview 使用指南 ## 📖 概述 `FormPreview` 是一个独立的表单预览组件,从 `FormDesigner` 中提取出来,可在任何地方使用。它支持完整的表单交互、验证和联动规则。 ## ✨ 特点 - ✅ **完全独立**:可在任何页面使用,不依赖 FormDesigner - ✅ **支持所有字段类型**:input, select, textarea, date, grid, cascader 等 - ✅ **支持验证规则**:required, pattern, min/max, email, phone 等 - ✅ **支持联动规则**:显示/隐藏、禁用/启用、必填控制、值联动 - ✅ **支持动态数据源**:API 数据源、预定义数据源 - ✅ **非受控组件**:内部管理状态,无冲突 - ✅ **简单易用**:只需传入 `fields` 和 `formConfig` ## 📦 导入 ```typescript import { FormPreview, FormPreviewRef } from '@/components/FormDesigner'; import type { FieldConfig, FormConfig } from '@/components/FormDesigner'; ``` ## 🚀 基础用法 ### 1. 最简单的使用 ```tsx import React, { useRef } from 'react'; import { FormPreview, FormPreviewRef } from '@/components/FormDesigner'; const MyComponent = () => { const previewRef = useRef(null); // 从后端获取表单定义 const formSchema = await getFormDefinitionById(id); return ( ); }; ``` ### 2. 在 Modal 中使用 ```tsx import React from 'react'; import { Modal } from 'antd'; import { FormPreview } from '@/components/FormDesigner'; const FormPreviewModal = ({ open, onClose, formDefinition }) => { if (!formDefinition) return null; const { schema } = formDefinition; return ( ); }; ``` ### 3. 使用 Ref 方法 ```tsx import React, { useRef } from 'react'; import { Button } from 'antd'; import { FormPreview, FormPreviewRef } from '@/components/FormDesigner'; const MyComponent = () => { const previewRef = useRef(null); const handleSubmit = async () => { // 触发表单验证和提交 await previewRef.current?.submit(); }; const handleReset = () => { // 重置表单 previewRef.current?.reset(); }; return (
); }; ``` ## 📝 Props 说明 ### FormPreviewProps | 属性 | 类型 | 必填 | 说明 | |------|------|------|------| | `fields` | `FieldConfig[]` | ✅ | 字段列表 | | `formConfig` | `FormConfig` | ✅ | 表单配置 | ### FormPreviewRef 方法 | 方法 | 参数 | 返回值 | 说明 | |------|------|--------|------| | `submit()` | 无 | `Promise` | 提交表单(触发验证) | | `reset()` | 无 | `void` | 重置表单 | ## 🔧 数据格式 ### FormConfig 示例 ```typescript const formConfig: FormConfig = { title: "部署申请表单", // 表单标题(可选) formWidth: 600, // 表单弹窗宽度,单位px labelAlign: "right", // 标签对齐:left | right | top size: "middle" // 表单尺寸:small | middle | large }; ``` ### Fields 示例 ```typescript const fields: FieldConfig[] = [ // 基础输入框 { id: "field_1", type: "input", label: "应用名称", name: "appName", placeholder: "请输入应用名称", required: true, validationRules: [ { type: "required", message: "应用名称不能为空" }, { type: "maxLength", value: 50, message: "不能超过50个字符" } ] }, // 下拉选择(静态选项) { id: "field_2", type: "select", label: "环境选择", name: "environment", required: true, dataSourceType: "static", options: [ { label: "开发环境", value: "dev" }, { label: "测试环境", value: "test" }, { label: "生产环境", value: "prod" } ] }, // 下拉选择(API 数据源) { id: "field_3", type: "select", label: "Jenkins服务器", name: "jenkinsServer", required: true, dataSourceType: "api", apiDataSource: { url: "/api/v1/jenkins-servers/list", method: "GET", params: { enabled: true }, labelField: "name", valueField: "id" } }, // 下拉选择(预定义数据源) { id: "field_4", type: "select", label: "项目组", name: "projectGroup", required: true, dataSourceType: "predefined", predefinedDataSource: { sourceType: "PROJECT_GROUPS" } }, // 栅格布局 { id: "field_5", type: "grid", label: "基础信息", name: "grid_basic", columns: 2, columnSpans: [12, 12], gutter: 16, children: [ // 第一列 [ { id: "field_6", type: "input", label: "创建人", name: "creator", required: true } ], // 第二列 [ { id: "field_7", type: "date", label: "创建日期", name: "createDate", required: true } ] ] } ]; ``` ## 🌟 实际应用场景 ### 场景1:工作流设计页面预览启动表单 ```tsx // src/pages/Workflow/Design/components/FormPreviewModal.tsx import { FormPreview } from '@/components/FormDesigner'; const FormPreviewModal = ({ formDefinition, open, onClose }) => { const { schema } = formDefinition; return ( ); }; ``` ### 场景2:表单设计器内部预览 ```tsx // src/components/FormDesigner/Designer.tsx const FormDesigner = () => { const [previewVisible, setPreviewVisible] = useState(false); const [fields, setFields] = useState([]); const [formConfig, setFormConfig] = useState({}); return ( <> setPreviewVisible(false)}> ); }; ``` ### 场景3:独立的表单预览页面 ```tsx // src/pages/Form/Preview/index.tsx import { useParams } from 'react-router-dom'; import { FormPreview } from '@/components/FormDesigner'; const FormPreviewPage = () => { const { id } = useParams(); const [formSchema, setFormSchema] = useState(null); useEffect(() => { const loadForm = async () => { const data = await getFormDefinitionById(id); setFormSchema(data.schema); }; loadForm(); }, [id]); if (!formSchema) return
加载中...
; return (

表单预览

); }; ``` ## ⚠️ 重要说明 ### 1. 非受控组件 `FormPreview` 是**非受控组件**,内部通过 `Ant Design Form` 管理状态: - ✅ **不要**传递 `value` 和 `onChange`(会导致冲突) - ✅ **不要**尝试从外部控制字段值 - ✅ 使用 `ref` 方法获取表单值或提交表单 ### 2. 数据格式统一 无论在哪里使用,数据格式都是一致的: ```typescript ``` ### 3. 与 FormRenderer 的区别 | 特性 | FormPreview | FormRenderer | |------|-------------|--------------| | 推荐使用 | ✅ 是 | ❌ 已废弃 | | 受控模式 | ❌ 非受控 | ⚠️ 部分受控(有问题) | | 下拉框可选中 | ✅ 正常 | ❌ 有bug | | 使用场景 | 预览、交互 | 已废弃 | **建议**:所有新代码都使用 `FormPreview`,不要再使用 `FormRenderer`。 ## 📚 相关文档 - [FormDesigner 文档](./README.md) - [字段类型定义](./types.ts) - [工作流扩展字段](./extensions/workflow/README.md)