refactor(form-builder): 优化表单项渲染及动态更新处理

- 使用 Select、Radio.Group 和 Checkbox.Group 的 options 属性简化渲染逻辑
- 针对 Checkbox 支持列布局时保留原有 Row/Col 结构,保证布局一致性
- 增加 renderDynamicFormItem 函数,统一处理动态更新表单项的渲染逻辑
- 优化动态表单项渲染时对 shouldUpdate 和 dependencies 的支持,改进联动效果
- 在渲染其他类型表单项时添加隐藏判断,避免不必要渲染
- 调整表单列表内部动态表单项的渲染顺序,保证联动功能正常
- 移除冗余代码,提升代码可读性和维护性
1.0
LiuJiaNan 2026-08-03 15:18:52 +08:00
parent 4a9284505b
commit 565d219449
1 changed files with 70 additions and 80 deletions

View File

@ -302,64 +302,38 @@ const FormItemsRenderer = ({
case FORM_ITEM_RENDER_ENUM.SELECT: case FORM_ITEM_RENDER_ENUM.SELECT:
return ( return (
<Select placeholder={placeholder} showSearch={{ optionFilterProp: "children" }} allowClear {...componentProps}> <Select
{(option.items || []).map((item) => { placeholder={placeholder}
const { value, label, disabled } = getSelectableItemAttributes(item, itemsFieldKey); showSearch={{ optionFilterProp: "label" }}
return ( allowClear
<Select.Option key={value} value={value} disabled={disabled}> options={(option.items || []).map(item => getSelectableItemAttributes(item, itemsFieldKey))}
{label} {...componentProps}
</Select.Option> />
);
})}
</Select>
); );
case FORM_ITEM_RENDER_ENUM.RADIO: case FORM_ITEM_RENDER_ENUM.RADIO:
return ( return <Radio.Group options={(option.items || []).map(item => getSelectableItemAttributes(item, itemsFieldKey))} {...componentProps} />;
<Radio.Group {...componentProps}>
{(option.items || []).map((item) => {
const { value, label, disabled } = getSelectableItemAttributes(item, itemsFieldKey);
return (
<Radio key={value} value={value} disabled={disabled}>
{label}
</Radio>
);
})}
</Radio.Group>
);
case FORM_ITEM_RENDER_ENUM.CHECKBOX: case FORM_ITEM_RENDER_ENUM.CHECKBOX: {
const selectableOptions = (option.items || []).map(item => getSelectableItemAttributes(item, itemsFieldKey));
// checkboxCol 时需要栅格布局Checkbox.Group 的 options 不支持列布局,此处使用 children + Row/Col 保持原有行为
if (option.checkboxCol) {
return ( return (
<Checkbox.Group {...componentProps}> <Checkbox.Group {...componentProps}>
{
option.checkboxCol
? (
<Row> <Row>
{(option.items || []).map((item) => { {selectableOptions.map(({ value, label, disabled }) => (
const { value, label, disabled } = getSelectableItemAttributes(item, itemsFieldKey);
return (
<Col span={option.checkboxCol} key={value}> <Col span={option.checkboxCol} key={value}>
<Checkbox value={value} disabled={disabled}> <Checkbox value={value} disabled={disabled}>
{label} {label}
</Checkbox> </Checkbox>
</Col> </Col>
); ))}
})}
</Row> </Row>
)
: (
(option.items || []).map((item) => {
const { value, label, disabled } = getSelectableItemAttributes(item, itemsFieldKey);
return (
<Checkbox key={value} value={value} disabled={disabled}>
{label}
</Checkbox>
);
})
)
}
</Checkbox.Group> </Checkbox.Group>
); );
}
return <Checkbox.Group options={selectableOptions} {...componentProps} />;
}
case FORM_ITEM_RENDER_ENUM.DATE: case FORM_ITEM_RENDER_ENUM.DATE:
return <DatePicker placeholder={placeholder} format="YYYY-MM-DD" style={{ width: "100%" }} {...componentProps} />; return <DatePicker placeholder={placeholder} format="YYYY-MM-DD" style={{ width: "100%" }} {...componentProps} />;
@ -485,6 +459,9 @@ const FormItemsRenderer = ({
const renderOtherTypeItem = ({ option, style, col, index, preserve }) => { const renderOtherTypeItem = ({ option, style, col, index, preserve }) => {
const componentProps = getComponentProps(option); const componentProps = getComponentProps(option);
if (getHidden(option.hidden))
return null;
// 如果是 customizeRender 类型,完全交给外部控制渲染 // 如果是 customizeRender 类型,完全交给外部控制渲染
if (option.customizeRender) { if (option.customizeRender) {
return ( return (
@ -520,30 +497,14 @@ const FormItemsRenderer = ({
return null; return null;
}; };
// 渲染需要动态更新的表单项
const renderDynamicFormItem = ({ option, index, style, col, preserve }) => {
const formItemProps = getFormItemProps(option);
return (
<Form.Item
key={getKey(option) || index}
noStyle
preserve={preserve}
shouldUpdate={option.shouldUpdate ?? formItemProps.shouldUpdate}
dependencies={option.dependencies ?? formItemProps.dependencies}
>
{() => {
return renderFormItem({ option, style, col, index, preserve });
}}
</Form.Item>
);
};
// 渲染 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);
if (getHidden(option.hidden))
return null;
return ( return (
<Col key={getKey(option) || index} span={col.span} style={{ ...style, ...getColStyle(option) }}> <Col key={getKey(option) || index} span={col.span} style={{ ...style, ...getColStyle(option) }}>
{getColTitle(option)} {getColTitle(option)}
@ -568,6 +529,12 @@ const FormItemsRenderer = ({
index: `${fieldIndex}_${listIndex}`, index: `${fieldIndex}_${listIndex}`,
preserve: true, preserve: true,
}; };
// 如果配置了 shouldUpdate 或 dependencies使用 Form.Item 的联动机制
// 注意:动态检测必须在 renderOtherTypeItem 之前否则特殊类型customizeRender / onlyForLabel / DIVIDER无法响应联动
if (getIsDynamicFormItem(listOption, formItemProps))
return renderDynamicFormItem(params);
const otherTypeItem = renderOtherTypeItem(params); const otherTypeItem = renderOtherTypeItem(params);
if (otherTypeItem) if (otherTypeItem)
return otherTypeItem; return otherTypeItem;
@ -575,9 +542,6 @@ const FormItemsRenderer = ({
if (listOption.render === FORM_ITEM_RENDER_ENUM.FORM_LIST) if (listOption.render === FORM_ITEM_RENDER_ENUM.FORM_LIST)
return renderFormList(params); return renderFormList(params);
if (getIsDynamicFormItem(listOption, formItemProps))
return renderDynamicFormItem(params);
// 从后往前查找最后一个普通可见表单项,特殊项不允许承载操作按钮。 // 从后往前查找最后一个普通可见表单项,特殊项不允许承载操作按钮。
const findLastButtonIndex = () => { const findLastButtonIndex = () => {
for (let i = listOptions.length - 1; i >= 0; i--) { for (let i = listOptions.length - 1; i >= 0; i--) {
@ -662,6 +626,32 @@ const FormItemsRenderer = ({
); );
}; };
// 渲染需要动态更新的表单项
const renderDynamicFormItem = ({ option, index, style, col, preserve }) => {
const formItemProps = getFormItemProps(option);
return (
<Form.Item
key={getKey(option) || index}
noStyle
preserve={preserve}
shouldUpdate={option.shouldUpdate ?? formItemProps.shouldUpdate}
dependencies={option.dependencies ?? formItemProps.dependencies}
>
{() => {
const otherTypeItem = renderOtherTypeItem({ option, style, col, index, preserve });
if (otherTypeItem)
return otherTypeItem;
if (option.render === FORM_ITEM_RENDER_ENUM.FORM_LIST)
return renderFormList({ option, index, col, style });
return renderFormItem({ option, style, col, index, preserve });
}}
</Form.Item>
);
};
return ( return (
<> <>
{options.map((option, index) => { {options.map((option, index) => {
@ -677,6 +667,10 @@ const FormItemsRenderer = ({
preserve: false, preserve: false,
}; };
// 如果配置了 shouldUpdate 或 dependencies使用 Form.Item 的联动机制
if (getIsDynamicFormItem(option, formItemProps))
return renderDynamicFormItem(params);
// 处理特殊类型的表单项 // 处理特殊类型的表单项
const otherTypeItem = renderOtherTypeItem(params); const otherTypeItem = renderOtherTypeItem(params);
if (otherTypeItem) if (otherTypeItem)
@ -686,10 +680,6 @@ const FormItemsRenderer = ({
if (option.render === FORM_ITEM_RENDER_ENUM.FORM_LIST) if (option.render === FORM_ITEM_RENDER_ENUM.FORM_LIST)
return renderFormList(params); return renderFormList(params);
// 如果配置了 shouldUpdate 或 dependencies使用 Form.Item 的联动机制
if (getIsDynamicFormItem(option, formItemProps))
return renderDynamicFormItem(params);
// 普通表单项(静态配置) // 普通表单项(静态配置)
return renderFormItem(params); return renderFormItem(params);
})} })}