问题
代码当中有多个tab,会循环渲染多个Form(底层是用elment-plus的Form二次封装的),多个Form共用一个ref,这样导致的问题是tab切换时,上一个tab的表单项还会校验,需求是只校验当前tab的表单项。
function renderForm(tab: string) {
if (!widgetRef.value![tab]) return null;
const { props, template } = widgetRef.value![tab];
const { itemWidth, size, labelWidth, disabled, effects } = props;
const formProps = {};
itemWidth && (formProps['item-width'] = itemWidth);
labelWidth && (formProps['label-width'] = labelWidth);
size && (formProps['size'] = size);
disabled !== false && (formProps['disabled'] = disabled);
return (
<Form ref={formRef} model={dataRef.value} {...formProps}>
{template.map((node) => renderComponent(node, effects, tab))}
</Form>
);
}
问题分析
查看element-plus源码后发现,el-form的validate方法会循环校验每个field,返回一个Promise
结合上述问题分析,formRef还绑定的是上一个tab的表单实例,没有更新过来,导致校验的是上一个tab的表单项
解决方案
function renderForm(tab: string) {
if (!widgetRef.value![tab]) return null;
const { props, template } = widgetRef.value![tab];
const { itemWidth, size, labelWidth, disabled, effects } = props;
const formProps = {};
itemWidth && (formProps['item-width'] = itemWidth);
labelWidth && (formProps['label-width'] = labelWidth);
size && (formProps['size'] = size);
disabled !== false && (formProps['disabled'] = disabled);
// 此处多个Form用不同的ref,ref实例存储存储在一个对象中,解决了tab切换时,上一个tab的表单项还会校验问题
const ref = [PageTypeEnum.Setting, PageTypeEnum.TenantSetting].includes(pageTypeRef.value)
? formRef[tab]
: formRef;
return (
<Form ref={ref} model={dataRef.value} {...formProps}>
{template.map((node) => renderComponent(node, effects, tab))}
</Form>
);
}