refactor(form-builder): 优化表单项渲染及动态更新处理
- 使用 Select、Radio.Group 和 Checkbox.Group 的 options 属性简化渲染逻辑 - 针对 Checkbox 支持列布局时保留原有 Row/Col 结构,保证布局一致性 - 增加 renderDynamicFormItem 函数,统一处理动态更新表单项的渲染逻辑 - 优化动态表单项渲染时对 shouldUpdate 和 dependencies 的支持,改进联动效果 - 在渲染其他类型表单项时添加隐藏判断,避免不必要渲染 - 调整表单列表内部动态表单项的渲染顺序,保证联动功能正常 - 移除冗余代码,提升代码可读性和维护性1.0
parent
4a9284505b
commit
565d219449
|
|
@ -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: {
|
||||||
return (
|
const selectableOptions = (option.items || []).map(item => getSelectableItemAttributes(item, itemsFieldKey));
|
||||||
<Checkbox.Group {...componentProps}>
|
// checkboxCol 时需要栅格布局,Checkbox.Group 的 options 不支持列布局,此处使用 children + Row/Col 保持原有行为
|
||||||
{
|
if (option.checkboxCol) {
|
||||||
option.checkboxCol
|
return (
|
||||||
? (
|
<Checkbox.Group {...componentProps}>
|
||||||
<Row>
|
<Row>
|
||||||
{(option.items || []).map((item) => {
|
{selectableOptions.map(({ value, label, disabled }) => (
|
||||||
const { value, label, disabled } = getSelectableItemAttributes(item, itemsFieldKey);
|
<Col span={option.checkboxCol} key={value}>
|
||||||
return (
|
<Checkbox value={value} disabled={disabled}>
|
||||||
<Col span={option.checkboxCol} key={value}>
|
{label}
|
||||||
<Checkbox value={value} disabled={disabled}>
|
</Checkbox>
|
||||||
{label}
|
</Col>
|
||||||
</Checkbox>
|
))}
|
||||||
</Col>
|
</Row>
|
||||||
);
|
</Checkbox.Group>
|
||||||
})}
|
);
|
||||||
</Row>
|
}
|
||||||
)
|
return <Checkbox.Group options={selectableOptions} {...componentProps} />;
|
||||||
: (
|
}
|
||||||
(option.items || []).map((item) => {
|
|
||||||
const { value, label, disabled } = getSelectableItemAttributes(item, itemsFieldKey);
|
|
||||||
return (
|
|
||||||
<Checkbox key={value} value={value} disabled={disabled}>
|
|
||||||
{label}
|
|
||||||
</Checkbox>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</Checkbox.Group>
|
|
||||||
);
|
|
||||||
|
|
||||||
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);
|
||||||
})}
|
})}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue