feat(form): formList支持formList无限嵌套

master
LiuJiaNan 2026-04-24 16:20:49 +08:00
parent 77f6113013
commit cc92b6e59c
1 changed files with 31 additions and 17 deletions

View File

@ -257,8 +257,8 @@ const FormItemsRenderer = ({
const componentProps = getComponentProps(option); const componentProps = getComponentProps(option);
const itemsFieldKey = getItemsFieldKey(option); const itemsFieldKey = getItemsFieldKey(option);
/** @type {string | Function} */ /** @type {string | Function} */
const render = option.render || FORM_ITEM_RENDER_ENUM.INPUT; const render = option.render ?? FORM_ITEM_RENDER_ENUM.INPUT;
const placeholder = option.placeholder || `${[FORM_ITEM_RENDER_ENUM.INPUT, FORM_ITEM_RENDER_ENUM.TEXTAREA, FORM_ITEM_RENDER_ENUM.INPUT_NUMBER, FORM_ITEM_RENDER_ENUM.NUMBER, FORM_ITEM_RENDER_ENUM.INTEGER].includes(render) ? "输入" : "选择"}${option.label}`; const placeholder = option.placeholder ?? `${[FORM_ITEM_RENDER_ENUM.INPUT, FORM_ITEM_RENDER_ENUM.TEXTAREA, FORM_ITEM_RENDER_ENUM.INPUT_NUMBER, FORM_ITEM_RENDER_ENUM.NUMBER, FORM_ITEM_RENDER_ENUM.INTEGER].includes(render) ? "输入" : "选择"}${option.label}`;
switch (render) { switch (render) {
case FORM_ITEM_RENDER_ENUM.INPUT: case FORM_ITEM_RENDER_ENUM.INPUT:
@ -442,6 +442,8 @@ const FormItemsRenderer = ({
labelCol={col.labelCol} labelCol={col.labelCol}
wrapperCol={col.wrapperCol} wrapperCol={col.wrapperCol}
preserve={false} preserve={false}
required={renderLabel(option) === " " ? false : getRequired(option.required)}
colon={renderLabel(option) !== " "}
{...formItemProps} {...formItemProps}
> >
{renderFormControl(option)} {renderFormControl(option)}
@ -490,7 +492,7 @@ const FormItemsRenderer = ({
}; };
// 渲染 Form.List // 渲染 Form.List
const renderFormList = (option, index, col, style) => { const renderFormList = ({ option, index, col, style }) => {
const formListUniqueProps = getFormListUniqueProps(option); const formListUniqueProps = getFormListUniqueProps(option);
const componentProps = getComponentProps(option); const componentProps = getComponentProps(option);
@ -519,9 +521,15 @@ const FormItemsRenderer = ({
if (otherTypeItem) if (otherTypeItem)
return otherTypeItem; return otherTypeItem;
// 如果是最后一个表单项,则在其后添加操作按钮 if (listOption.render === FORM_ITEM_RENDER_ENUM.FORM_LIST)
// 这样可以确保每个表单项组都有添加/删除按钮 return renderFormList(params);
if (listIndex === listOptions.length - 1) {
// 判断下一个是否是嵌套的 FormList如果是则在当前项后添加按钮
const nextOption = listOptions[listIndex + 1];
const isNextNestedFormList = nextOption && nextOption.render === FORM_ITEM_RENDER_ENUM.FORM_LIST;
// 如果是最后一个表单项,或者下一个是嵌套的 FormList则在其后添加操作按钮
if (listIndex === listOptions.length - 1 || isNextNestedFormList) {
return ( return (
<Col key={getKey(listOption) || listIndex} span={col.span} style={style}> <Col key={getKey(listOption) || listIndex} span={col.span} style={style}>
<Form.Item <Form.Item
@ -529,7 +537,8 @@ const FormItemsRenderer = ({
labelCol={col.labelCol} labelCol={col.labelCol}
wrapperCol={col.wrapperCol} wrapperCol={col.wrapperCol}
preserve={false} preserve={false}
required={getRequired(listOption.required)} required={renderLabel(listOption) === " " ? false : getRequired(listOption.required)}
colon={renderLabel(listOption) !== " "}
{...formItemProps} {...formItemProps}
> >
<div style={{ display: "flex", gap: 10, alignItems: "center", justifyContent: "space-between" }}> <div style={{ display: "flex", gap: 10, alignItems: "center", justifyContent: "space-between" }}>
@ -589,7 +598,7 @@ const FormItemsRenderer = ({
}; };
// 渲染需要动态更新的表单项 // 渲染需要动态更新的表单项
const renderDynamicFormItem = (option, index, style, col) => { const renderDynamicFormItem = ({ option, index, style, col }) => {
const formItemProps = getFormItemProps(option); const formItemProps = getFormItemProps(option);
return ( return (
@ -614,23 +623,28 @@ const FormItemsRenderer = ({
const style = getStyle(index); const style = getStyle(index);
const formItemProps = getFormItemProps(option); const formItemProps = getFormItemProps(option);
const params = {
option,
style,
col,
index,
};
// 处理特殊类型的表单项 // 处理特殊类型的表单项
const otherTypeItem = renderOtherTypeItem({ option, style, col, index }); const otherTypeItem = renderOtherTypeItem(params);
if (otherTypeItem) if (otherTypeItem)
return otherTypeItem; return otherTypeItem;
// 如果是 Form.List // 如果是 Form.List
if (option.render === FORM_ITEM_RENDER_ENUM.FORM_LIST) { if (option.render === FORM_ITEM_RENDER_ENUM.FORM_LIST)
return renderFormList(option, index, col, style); return renderFormList(params);
}
// 如果配置了 shouldUpdate 或 dependencies使用 Form.Item 的联动机制 // 如果配置了 shouldUpdate 或 dependencies使用 Form.Item 的联动机制
if ((option.shouldUpdate ?? option.dependencies) || (formItemProps.shouldUpdate ?? formItemProps.dependencies)) { if ((option.shouldUpdate ?? option.dependencies) || (formItemProps.shouldUpdate ?? formItemProps.dependencies))
return renderDynamicFormItem(option, index, style, col); return renderDynamicFormItem(params);
}
// 普通表单项(静态配置) // 普通表单项(静态配置)
return renderFormItem({ option, style, col, index }); return renderFormItem(params);
})} })}
</> </>
); );