FormBuilder增加支持Form.List渲染
parent
d258739d63
commit
a131883abc
|
|
@ -45,6 +45,7 @@ const FormBuilder = (props) => {
|
||||||
options={options}
|
options={options}
|
||||||
labelCol={labelCol}
|
labelCol={labelCol}
|
||||||
span={span}
|
span={span}
|
||||||
|
gutter={gutter}
|
||||||
useAutoGenerateRequired={useAutoGenerateRequired}
|
useAutoGenerateRequired={useAutoGenerateRequired}
|
||||||
initialValues={values}
|
initialValues={values}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
import type { ColProps } from "antd/es/col";
|
import type { ColProps } from "antd/es/col";
|
||||||
import type { FormItemProps, Rule } from "antd/es/form";
|
import type { FormItemProps, Rule } from "antd/es/form";
|
||||||
|
import type { FormListFieldData } from "antd/es/form/FormList";
|
||||||
|
import type { Gutter } from "antd/es/grid/row";
|
||||||
import type { NamePath } from "rc-field-form/lib/interface";
|
import type { NamePath } from "rc-field-form/lib/interface";
|
||||||
import type { FC, ReactNode } from "react";
|
import type { FC, ReactNode } from "react";
|
||||||
import type { FORM_ITEM_RENDER_ENUM } from "../../enum/formItemRender";
|
import type { FORM_ITEM_RENDER_ENUM } from "../../enum/formItemRender";
|
||||||
|
|
@ -37,6 +39,26 @@ export interface itemsFieldConfig {
|
||||||
*/
|
*/
|
||||||
export type FormValues = Record<string, any>;
|
export type FormValues = Record<string, any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Form.List 独有的属性
|
||||||
|
*/
|
||||||
|
export interface FormListUniqueProps {
|
||||||
|
/** 是否显示新增按钮,默认 true */
|
||||||
|
showAddButton?: boolean;
|
||||||
|
/** 是否显示删除按钮,默认 true */
|
||||||
|
showRemoveButton?: boolean;
|
||||||
|
/** 新增按钮的文本,默认 '添加' */
|
||||||
|
addButtonText?: string;
|
||||||
|
/** 删除按钮的文本,默认 '删除' */
|
||||||
|
removeButtonText?: string;
|
||||||
|
/** 表单配置项 */
|
||||||
|
options: FormOption[] | ((field: FormListFieldData) => FormOption[]);
|
||||||
|
/** 点击新增按钮时的默认值 */
|
||||||
|
addDefaultValue?: FormValues;
|
||||||
|
/** 点击新增按钮时插入的索引位置 */
|
||||||
|
addInsertIndex?: number;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单配置项
|
* 表单配置项
|
||||||
*/
|
*/
|
||||||
|
|
@ -81,6 +103,8 @@ export interface FormOption {
|
||||||
dependencies?: NamePath[];
|
dependencies?: NamePath[];
|
||||||
/** 是否仅用于保存标签,不渲染到页面上,只在表单中保存数据,默认 false */
|
/** 是否仅用于保存标签,不渲染到页面上,只在表单中保存数据,默认 false */
|
||||||
onlyForLabel?: boolean;
|
onlyForLabel?: boolean;
|
||||||
|
/** Form.List 独有的属性 */
|
||||||
|
formListUniqueProps?: FormListUniqueProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -97,6 +121,10 @@ export interface FormItemsRendererProps {
|
||||||
useAutoGenerateRequired?: boolean;
|
useAutoGenerateRequired?: boolean;
|
||||||
/** 初始值,用于在表单未初始化时提供默认值 */
|
/** 初始值,用于在表单未初始化时提供默认值 */
|
||||||
initialValues?: FormValues;
|
initialValues?: FormValues;
|
||||||
|
/** 栅格间距,继承自 FormBuilder */
|
||||||
|
gutter?: Gutter | [Gutter, Gutter];
|
||||||
|
/** label 栅格配置,继承自 FormBuilder */
|
||||||
|
labelCol?: ColProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { InfoCircleOutlined } from "@ant-design/icons";
|
import { InfoCircleOutlined } from "@ant-design/icons";
|
||||||
import {
|
import {
|
||||||
|
Button,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
Col,
|
Col,
|
||||||
DatePicker,
|
DatePicker,
|
||||||
|
|
@ -8,6 +9,7 @@ import {
|
||||||
Input,
|
Input,
|
||||||
InputNumber,
|
InputNumber,
|
||||||
Radio,
|
Radio,
|
||||||
|
Row,
|
||||||
Select,
|
Select,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
} from "antd";
|
} from "antd";
|
||||||
|
|
@ -19,10 +21,19 @@ const { RangePicker } = DatePicker;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单项渲染器组件
|
* 表单项渲染器组件
|
||||||
|
* @param {object} props - 组件属性
|
||||||
|
* @param {Array} props.options - 表单配置项数组
|
||||||
|
* @param {object} props.labelCol - label 栅格配置
|
||||||
|
* @param {number} props.gutter - 栅格间距
|
||||||
|
* @param {number} props.span - 默认栅格占据列数
|
||||||
|
* @param {boolean} props.collapse - 是否折叠(仅显示前3项)
|
||||||
|
* @param {boolean} props.useAutoGenerateRequired - 是否自动生成必填规则
|
||||||
|
* @param {object} props.initialValues - 初始值
|
||||||
*/
|
*/
|
||||||
const FormItemsRenderer = ({
|
const FormItemsRenderer = ({
|
||||||
options,
|
options,
|
||||||
labelCol,
|
labelCol,
|
||||||
|
gutter = 24,
|
||||||
span = 12,
|
span = 12,
|
||||||
collapse = false,
|
collapse = false,
|
||||||
useAutoGenerateRequired = true,
|
useAutoGenerateRequired = true,
|
||||||
|
|
@ -47,6 +58,31 @@ const FormItemsRenderer = ({
|
||||||
: (option.componentProps || {});
|
: (option.componentProps || {});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 获取 Form.List 独有的属性
|
||||||
|
const getFormListUniqueProps = (option) => {
|
||||||
|
const defaultProps = {
|
||||||
|
showAddButton: true,
|
||||||
|
showRemoveButton: true,
|
||||||
|
addButtonText: "添加",
|
||||||
|
removeButtonText: "删除",
|
||||||
|
options: [],
|
||||||
|
addDefaultValue: {},
|
||||||
|
addInsertIndex: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (typeof option.formListUniqueProps === "function") {
|
||||||
|
return {
|
||||||
|
...defaultProps,
|
||||||
|
...option.formListUniqueProps(getFormValues()),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...defaultProps,
|
||||||
|
...(option.formListUniqueProps || {}),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
// 获取传给formItem的属性
|
// 获取传给formItem的属性
|
||||||
const getFormItemProps = (option) => {
|
const getFormItemProps = (option) => {
|
||||||
const formItemProps = typeof option.formItemProps === "function"
|
const formItemProps = typeof option.formItemProps === "function"
|
||||||
|
|
@ -92,6 +128,14 @@ const FormItemsRenderer = ({
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 获取 required
|
||||||
|
const getRequired = (required) => {
|
||||||
|
// 支持动态计算 required
|
||||||
|
return typeof required === "function"
|
||||||
|
? required(getFormValues())
|
||||||
|
: (required ?? true);
|
||||||
|
};
|
||||||
|
|
||||||
// 获取验证规则
|
// 获取验证规则
|
||||||
const getRules = (option) => {
|
const getRules = (option) => {
|
||||||
if (option.render === FORM_ITEM_RENDER_ENUM.DIVIDER)
|
if (option.render === FORM_ITEM_RENDER_ENUM.DIVIDER)
|
||||||
|
|
@ -115,11 +159,11 @@ const FormItemsRenderer = ({
|
||||||
rules.push({ pattern: /^(\d+)(\.\d{1,2})?$/, message: "请输入正确的数字,最多保留两位小数" });
|
rules.push({ pattern: /^(\d+)(\.\d{1,2})?$/, message: "请输入正确的数字,最多保留两位小数" });
|
||||||
rules.push({
|
rules.push({
|
||||||
validator: (_, value) => {
|
validator: (_, value) => {
|
||||||
if (value && Math.abs(parseFloat(value)) > Number.MAX_SAFE_INTEGER) {
|
if (value && Math.abs(Number.parseFloat(value)) > Number.MAX_SAFE_INTEGER) {
|
||||||
return Promise.reject("输入数值超出安全范围");
|
return Promise.reject("输入数值超出安全范围");
|
||||||
}
|
}
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -127,12 +171,7 @@ const FormItemsRenderer = ({
|
||||||
if (!useAutoGenerateRequired)
|
if (!useAutoGenerateRequired)
|
||||||
return option.rules ? (Array.isArray(option.rules) ? [...option.rules, ...rules] : [option.rules, ...rules]) : [];
|
return option.rules ? (Array.isArray(option.rules) ? [...option.rules, ...rules] : [option.rules, ...rules]) : [];
|
||||||
|
|
||||||
// 支持动态计算 required
|
if (getRequired(option.required)) {
|
||||||
const required = typeof option.required === "function"
|
|
||||||
? option.required(getFormValues())
|
|
||||||
: (option.required ?? true);
|
|
||||||
|
|
||||||
if (required) {
|
|
||||||
const isBlurTrigger = !option.render || [
|
const isBlurTrigger = !option.render || [
|
||||||
FORM_ITEM_RENDER_ENUM.INPUT,
|
FORM_ITEM_RENDER_ENUM.INPUT,
|
||||||
FORM_ITEM_RENDER_ENUM.TEXTAREA,
|
FORM_ITEM_RENDER_ENUM.TEXTAREA,
|
||||||
|
|
@ -162,6 +201,34 @@ const FormItemsRenderer = ({
|
||||||
return option.key || option.name;
|
return option.key || option.name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 使用 style 控制显示/隐藏
|
||||||
|
const getStyle = (index) => {
|
||||||
|
return collapse && index >= 3 ? { display: "none" } : undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 列数
|
||||||
|
const getCol = (option) => {
|
||||||
|
const itemSpan = option.render === FORM_ITEM_RENDER_ENUM.DIVIDER ? 24 : option.span ?? span;
|
||||||
|
const itemLabelCol = option.labelCol ?? (itemSpan === 24 ? { span: labelCol.span / 2 } : labelCol);
|
||||||
|
const itemWrapperCol = option.wrapperCol ?? { span: 24 - itemLabelCol.span };
|
||||||
|
return { span: itemSpan, labelCol: itemLabelCol, wrapperCol: itemWrapperCol };
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取 hidden
|
||||||
|
const getHidden = (hidden) => {
|
||||||
|
// 支持动态计算 hidden
|
||||||
|
return typeof hidden === "function"
|
||||||
|
? hidden(getFormValues())
|
||||||
|
: (hidden ?? false);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取 listOptions
|
||||||
|
const getListOptions = (listOptions, field) => {
|
||||||
|
return typeof listOptions === "function"
|
||||||
|
? listOptions(field)
|
||||||
|
: (listOptions ?? []);
|
||||||
|
};
|
||||||
|
|
||||||
// 渲染表单控件
|
// 渲染表单控件
|
||||||
const renderFormControl = (option) => {
|
const renderFormControl = (option) => {
|
||||||
const componentProps = getComponentProps(option);
|
const componentProps = getComponentProps(option);
|
||||||
|
|
@ -230,13 +297,37 @@ const FormItemsRenderer = ({
|
||||||
return <DatePicker placeholder={placeholder} format="YYYY-MM-DD" style={{ width: "100%" }} {...componentProps} />;
|
return <DatePicker placeholder={placeholder} format="YYYY-MM-DD" style={{ width: "100%" }} {...componentProps} />;
|
||||||
|
|
||||||
case FORM_ITEM_RENDER_ENUM.DATE_MONTH:
|
case FORM_ITEM_RENDER_ENUM.DATE_MONTH:
|
||||||
return <DatePicker picker="month" placeholder={placeholder} format="YYYY-MM" style={{ width: "100%" }} {...componentProps} />;
|
return (
|
||||||
|
<DatePicker
|
||||||
|
picker="month"
|
||||||
|
placeholder={placeholder}
|
||||||
|
format="YYYY-MM"
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
{...componentProps}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
case FORM_ITEM_RENDER_ENUM.DATE_YEAR:
|
case FORM_ITEM_RENDER_ENUM.DATE_YEAR:
|
||||||
return <DatePicker picker="year" placeholder={placeholder} format="YYYY" style={{ width: "100%" }} {...componentProps} />;
|
return (
|
||||||
|
<DatePicker
|
||||||
|
picker="year"
|
||||||
|
placeholder={placeholder}
|
||||||
|
format="YYYY"
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
{...componentProps}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
case FORM_ITEM_RENDER_ENUM.DATE_WEEK:
|
case FORM_ITEM_RENDER_ENUM.DATE_WEEK:
|
||||||
return <DatePicker picker="week" placeholder={placeholder} format="YYYY-wo" style={{ width: "100%" }} {...componentProps} />;
|
return (
|
||||||
|
<DatePicker
|
||||||
|
picker="week"
|
||||||
|
placeholder={placeholder}
|
||||||
|
format="YYYY-wo"
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
{...componentProps}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
case FORM_ITEM_RENDER_ENUM.DATE_RANGE:
|
case FORM_ITEM_RENDER_ENUM.DATE_RANGE:
|
||||||
return (
|
return (
|
||||||
|
|
@ -293,21 +384,34 @@ const FormItemsRenderer = ({
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 渲染普通表单项
|
||||||
|
const renderFormItem = ({ option, style, col, index, name }) => {
|
||||||
|
if (getHidden(option.hidden))
|
||||||
|
return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Col key={getKey(option) || index} span={col.span} style={style}>
|
||||||
{options.map((option, index) => {
|
<Form.Item
|
||||||
// 列数
|
name={name || option.name}
|
||||||
const itemSpan = option.render === FORM_ITEM_RENDER_ENUM.DIVIDER ? 24 : option.span ?? span;
|
label={renderLabel(option)}
|
||||||
const itemLabelCol = option.labelCol ?? (itemSpan === 24 ? { span: labelCol.span / 2 } : labelCol);
|
rules={getRules(option)}
|
||||||
const itemWrapperCol = option.wrapperCol ?? { span: 24 - itemLabelCol.span };
|
labelCol={col.labelCol}
|
||||||
|
wrapperCol={col.wrapperCol}
|
||||||
// 使用 style 控制显示/隐藏
|
preserve={false}
|
||||||
const style = collapse && index >= 3 ? { display: "none" } : undefined;
|
{...getFormItemProps(option)}
|
||||||
|
>
|
||||||
|
{renderFormControl(option)}
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 渲染特殊类型的表单项
|
||||||
|
const renderOtherTypeItem = ({ option, style, col, index, name }) => {
|
||||||
// 如果是 customizeRender 类型,完全交给外部控制渲染
|
// 如果是 customizeRender 类型,完全交给外部控制渲染
|
||||||
if (option.customizeRender) {
|
if (option.customizeRender) {
|
||||||
return (
|
return (
|
||||||
<Col key={getKey(option) || index} span={itemSpan} style={style}>
|
<Col key={getKey(option) || index} span={col.span} style={style}>
|
||||||
{option.render}
|
{option.render}
|
||||||
</Col>
|
</Col>
|
||||||
);
|
);
|
||||||
|
|
@ -318,7 +422,7 @@ const FormItemsRenderer = ({
|
||||||
return (
|
return (
|
||||||
<Form.Item
|
<Form.Item
|
||||||
key={getKey(option) || index}
|
key={getKey(option) || index}
|
||||||
name={option.name}
|
name={name || option.name}
|
||||||
noStyle
|
noStyle
|
||||||
preserve={false}
|
preserve={false}
|
||||||
>
|
>
|
||||||
|
|
@ -330,75 +434,148 @@ const FormItemsRenderer = ({
|
||||||
// 如果是分割线
|
// 如果是分割线
|
||||||
if (option.render === FORM_ITEM_RENDER_ENUM.DIVIDER) {
|
if (option.render === FORM_ITEM_RENDER_ENUM.DIVIDER) {
|
||||||
return (
|
return (
|
||||||
<Col key={getKey(option) || index} span={itemSpan} style={style}>
|
<Col key={getKey(option) || index} span={col.span} style={style}>
|
||||||
<Divider orientation="left">{option.label}</Divider>
|
<Divider orientation="left">{option.label}</Divider>
|
||||||
</Col>
|
</Col>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果配置了 shouldUpdate 或 dependencies,使用 Form.Item 的联动机制
|
return null;
|
||||||
if ((option.shouldUpdate ?? option.dependencies) || (option?.componentProps?.shouldUpdate ?? option?.componentProps?.dependencies)) {
|
};
|
||||||
|
|
||||||
|
// 渲染 Form.List
|
||||||
|
const renderFormList = (option, index, col, style) => {
|
||||||
|
const formListUniqueProps = getFormListUniqueProps(option);
|
||||||
|
return (
|
||||||
|
<Col key={getKey(option) || index} span={col.span} style={style}>
|
||||||
|
<Form.List name={option.name}>
|
||||||
|
{(fields, { add, remove }) => (
|
||||||
|
<>
|
||||||
|
{fields.map((field, fieldIndex) => {
|
||||||
|
const listOptions = getListOptions(option.formListUniqueProps.options, field);
|
||||||
|
return (
|
||||||
|
<Row gutter={gutter} key={field.key}>
|
||||||
|
{listOptions.map((listOption, listIndex) => {
|
||||||
|
const col = getCol(listOption);
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
option: listOption,
|
||||||
|
style,
|
||||||
|
col,
|
||||||
|
index: `${fieldIndex}_${listIndex}`,
|
||||||
|
name: [field.name, listOption.name],
|
||||||
|
};
|
||||||
|
const otherTypeItem = renderOtherTypeItem(params);
|
||||||
|
if (otherTypeItem)
|
||||||
|
return otherTypeItem;
|
||||||
|
|
||||||
|
// 如果是最后一个表单项,则在其后添加操作按钮
|
||||||
|
// 这样可以确保每个表单项组都有添加/删除按钮
|
||||||
|
if (listIndex === listOptions.length - 1) {
|
||||||
|
return (
|
||||||
|
<Col key={getKey(listOption) || listIndex} span={col.span} style={style}>
|
||||||
|
<Form.Item
|
||||||
|
label={renderLabel(listOption)}
|
||||||
|
labelCol={col.labelCol}
|
||||||
|
wrapperCol={col.wrapperCol}
|
||||||
|
preserve={false}
|
||||||
|
required={getRequired(listOption.required)}
|
||||||
|
{...getFormItemProps(listOption)}
|
||||||
|
>
|
||||||
|
<div style={{ display: "flex", gap: 10, alignItems: "center" }}>
|
||||||
|
<Form.Item
|
||||||
|
noStyle
|
||||||
|
rules={getRules(listOption)}
|
||||||
|
name={[field.name, listOption.name]}
|
||||||
|
>
|
||||||
|
{renderFormControl(listOption)}
|
||||||
|
</Form.Item>
|
||||||
|
{
|
||||||
|
// 只有当不是第一行时才显示删除按钮
|
||||||
|
fieldIndex >= 1
|
||||||
|
? (
|
||||||
|
formListUniqueProps.showRemoveButton
|
||||||
|
&& (
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
danger
|
||||||
|
onClick={() => remove(field.name)}
|
||||||
|
>
|
||||||
|
{formListUniqueProps.removeButtonText}
|
||||||
|
</Button>
|
||||||
|
)
|
||||||
|
)
|
||||||
|
: (
|
||||||
|
// 第一行显示添加按钮
|
||||||
|
formListUniqueProps.showAddButton
|
||||||
|
&& (
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
onClick={() => add(formListUniqueProps.addDefaultValue, formListUniqueProps.addInsertIndex)}
|
||||||
|
>
|
||||||
|
{formListUniqueProps.addButtonText}
|
||||||
|
</Button>
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return renderFormItem(params);
|
||||||
|
})}
|
||||||
|
</Row>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Form.List>
|
||||||
|
</Col>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 渲染需要动态更新的表单项
|
||||||
|
const renderDynamicFormItem = (option, index, style, col) => {
|
||||||
return (
|
return (
|
||||||
<Form.Item
|
<Form.Item
|
||||||
key={getKey(option) || index}
|
key={getKey(option) || index}
|
||||||
noStyle
|
noStyle
|
||||||
preserve={false}
|
preserve={false}
|
||||||
shouldUpdate={option.shouldUpdate ?? option?.componentProps?.shouldUpdate}
|
shouldUpdate={option.shouldUpdate ?? option?.componentProps?.shouldUpdate}
|
||||||
dependencies={option.dependencies || option?.componentProps?.dependencies}
|
dependencies={option.dependencies ?? option?.componentProps?.dependencies}
|
||||||
>
|
>
|
||||||
{() => {
|
{() => {
|
||||||
// 支持动态计算 hidden
|
return renderFormItem({ option, style, col, index });
|
||||||
const hidden = typeof option.hidden === "function"
|
|
||||||
? option.hidden(getFormValues())
|
|
||||||
: (option.hidden ?? false);
|
|
||||||
|
|
||||||
if (hidden)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Col key={getKey(option) || index} span={itemSpan} style={style}>
|
|
||||||
<Form.Item
|
|
||||||
name={option.name}
|
|
||||||
label={renderLabel(option)}
|
|
||||||
rules={getRules(option)}
|
|
||||||
labelCol={itemLabelCol}
|
|
||||||
wrapperCol={itemWrapperCol}
|
|
||||||
preserve={false}
|
|
||||||
{...getFormItemProps(option)}
|
|
||||||
>
|
|
||||||
{renderFormControl(option)}
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
);
|
|
||||||
}}
|
}}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{options.map((option, index) => {
|
||||||
|
const col = getCol(option);
|
||||||
|
const style = getStyle(index);
|
||||||
|
|
||||||
|
// 处理特殊类型的表单项
|
||||||
|
const otherTypeItem = renderOtherTypeItem({ option, style, col, index });
|
||||||
|
if (otherTypeItem)
|
||||||
|
return otherTypeItem;
|
||||||
|
|
||||||
|
// 如果是 Form.List
|
||||||
|
if (option.render === FORM_ITEM_RENDER_ENUM.FORM_LIST) {
|
||||||
|
return renderFormList(option, index, col, style);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果配置了 shouldUpdate 或 dependencies,使用 Form.Item 的联动机制
|
||||||
|
if ((option.shouldUpdate ?? option.dependencies) || (option?.componentProps?.shouldUpdate ?? option?.componentProps?.dependencies)) {
|
||||||
|
return renderDynamicFormItem(option, index, style, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 普通表单项(静态配置)
|
// 普通表单项(静态配置)
|
||||||
// 支持动态计算 hidden
|
return renderFormItem({ option, style, col, index });
|
||||||
const hidden = typeof option.hidden === "function"
|
|
||||||
? option.hidden(getFormValues())
|
|
||||||
: (option.hidden ?? false);
|
|
||||||
|
|
||||||
if (hidden)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Col key={getKey(option) || index} span={itemSpan} style={style}>
|
|
||||||
<Form.Item
|
|
||||||
name={option.name}
|
|
||||||
label={renderLabel(option)}
|
|
||||||
rules={getRules(option)}
|
|
||||||
labelCol={itemLabelCol}
|
|
||||||
wrapperCol={itemWrapperCol}
|
|
||||||
preserve={false}
|
|
||||||
{...getFormItemProps(option)}
|
|
||||||
>
|
|
||||||
{renderFormControl(option)}
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
);
|
|
||||||
})}
|
})}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -32,4 +32,6 @@ export declare const FORM_ITEM_RENDER_ENUM: {
|
||||||
DATETIME_RANGE: "datetimeRange";
|
DATETIME_RANGE: "datetimeRange";
|
||||||
/** 映射为 antd Divider */
|
/** 映射为 antd Divider */
|
||||||
DIVIDER: "divider";
|
DIVIDER: "divider";
|
||||||
|
/** 映射为 antd FormList */
|
||||||
|
FORM_LIST: "formList",
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -32,4 +32,6 @@ export const FORM_ITEM_RENDER_ENUM = {
|
||||||
DATETIME_RANGE: "datetimeRange",
|
DATETIME_RANGE: "datetimeRange",
|
||||||
/** 映射为 antd Divider */
|
/** 映射为 antd Divider */
|
||||||
DIVIDER: "divider",
|
DIVIDER: "divider",
|
||||||
|
/** 映射为 antd FormList */
|
||||||
|
FORM_LIST: "formList",
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue