feat: 表单回调函数支持直接传入函数,增加一个扩展参数可以直接操控全表单字段的状态

This commit is contained in:
gaoyunqi
2024-02-18 16:57:55 +08:00
parent b61380ee1d
commit 53b5209c30
2 changed files with 666 additions and 905 deletions

File diff suppressed because it is too large Load Diff

View File

@ -2,52 +2,20 @@
<div>
<!--如果是grid 组件 需要新增grid布局包裹-->
<template v-if="schema.component.includes('Grid')">
<Row
v-show="getIsShow(schema)"
:align="(schema.componentProps as any ).align"
:gutter="(schema.componentProps as any ).gutter ?? 0"
:justify="(schema.componentProps as any ).justify"
type="flex"
>
<Row v-show="getIsShow(schema)" :align="(schema.componentProps as any ).align" :gutter="(schema.componentProps as any ).gutter ?? 0" :justify="(schema.componentProps as any ).justify" type="flex">
<Col v-for="(col, colIndex) in schema.children" :key="colIndex" :span="col.span">
<template v-for="childSchema in col.list" :key="childSchema.field">
<SimpleFormItem
v-if="showComponent(childSchema)"
v-model:value="formModel![childSchema.field]"
:form-api="formApi"
:isWorkFlow="isWorkFlow"
:label-col="labelCol"
:refreshFieldObj="refreshFieldObj"
:schema="childSchema"
/>
<SimpleFormItem v-if="showComponent(childSchema)" v-model:value="formModel![childSchema.field]" :form-api="formApi" :isWorkFlow="isWorkFlow" :label-col="labelCol" :refreshFieldObj="refreshFieldObj" :schema="childSchema" />
</template>
</Col>
</Row>
</template>
<!--如果是tab 组件 需要新增tab组件包裹-->
<template v-else-if="schema.component === 'Tab'">
<Tabs
v-show="getIsShow(schema)"
v-model:activeKey="activeKey"
:size="(schema.componentProps as any ).tabSize"
:tabPosition="(schema.componentProps as any ).tabPosition"
:type="(schema.componentProps as any ).type"
>
<TabPane
v-for="(tab, tabIndex) in schema.children"
:key="tabIndex"
:forceRender="true"
:tab="tab.name"
>
<Tabs v-show="getIsShow(schema)" v-model:activeKey="activeKey" :size="(schema.componentProps as any ).tabSize" :tabPosition="(schema.componentProps as any ).tabPosition" :type="(schema.componentProps as any ).type">
<TabPane v-for="(tab, tabIndex) in schema.children" :key="tabIndex" :forceRender="true" :tab="tab.name">
<template v-for="childSchema in tab.list" :key="childSchema.field">
<SimpleFormItem
v-if="showComponent(childSchema)"
v-model:value="formModel![childSchema.field]"
:form-api="formApi"
:isWorkFlow="isWorkFlow"
:refreshFieldObj="refreshFieldObj"
:schema="childSchema"
/>
<SimpleFormItem v-if="showComponent(childSchema)" v-model:value="formModel![childSchema.field]" :form-api="formApi" :isWorkFlow="isWorkFlow" :refreshFieldObj="refreshFieldObj" :schema="childSchema" />
</template>
</TabPane>
</Tabs>
@ -64,13 +32,7 @@
:name="schema.field"
:wrapperCol="itemLabelWidthProp.wrapperCol"
>
<component
:is="formComponent(schema)"
v-model:value="formModel![schema.field]"
:disabled="getDisable"
:size="formProps?.size"
v-bind="schema.componentProps"
/>
<component :is="formComponent(schema)" v-model:value="formModel![schema.field]" :disabled="getDisable" :size="formProps?.size" v-bind="schema.componentProps" />
</FormItem>
</template>
<!--如果是子表单 组件 需要v-model:value="表单对象[字段名]"-->
@ -85,14 +47,7 @@
:name="schema.field"
:wrapperCol="itemLabelWidthProp.wrapperCol"
>
<component
:is="componentMap.get(schema.component)"
v-model:value="formModel![schema.field]"
:disabled="getDisable"
:refreshFieldObj="refreshFieldObj"
:size="formProps?.size"
v-bind="schema.componentProps"
/>
<component :is="componentMap.get(schema.component)" v-model:value="formModel![schema.field]" :disabled="getDisable" :refreshFieldObj="refreshFieldObj" :size="formProps?.size" v-bind="schema.componentProps" />
</FormItem>
</template>
<template v-else-if="schema.component === 'TableLayout'">
@ -104,21 +59,11 @@
height: tdElement.height ? tdElement.height + 'px' : '',
minHeight: (tdElement.height || '42') + 'px',
overflow: 'hidden',
padding: '10px',
padding: '10px'
}"
>
<template
v-for="childSchema in tdElement.children"
:key="childSchema.field"
>
<SimpleFormItem
v-if="showComponent(childSchema)"
v-model:value="formModel![childSchema.field]"
:form-api="formApi"
:isWorkFlow="isWorkFlow"
:refreshFieldObj="refreshFieldObj"
:schema="childSchema"
/>
<template v-for="childSchema in tdElement.children" :key="childSchema.field">
<SimpleFormItem v-if="showComponent(childSchema)" v-model:value="formModel![childSchema.field]" :form-api="formApi" :isWorkFlow="isWorkFlow" :refreshFieldObj="refreshFieldObj" :schema="childSchema" />
</template>
</div>
</div>
@ -149,62 +94,24 @@
/>
</FormItem>
<!-- 因为Range会变为 开始时间 结束时间 2个属性给与表单数据 所以需要2个隐藏框绑定 starTime endTime -->
<FormItem
v-show="false"
:key="schema.key"
:label="getComponentsProps.showLabel ? schema.label : ''"
:name="schema.field.split(',')[0]"
>
<FormItem v-show="false" :key="schema.key" :label="getComponentsProps.showLabel ? schema.label : ''" :name="schema.field.split(',')[0]">
<input type="hidden" />
</FormItem>
<FormItem
v-show="false"
:key="schema.key"
:label="getComponentsProps.showLabel ? schema.label : ''"
:name="schema.field.split(',')[1]"
>
<FormItem v-show="false" :key="schema.key" :label="getComponentsProps.showLabel ? schema.label : ''" :name="schema.field.split(',')[1]">
<input type="hidden" />
</FormItem>
</template>
<!--如果checked 或者 switch组件 需要v-model:checked="表单对象[字段名]" "-->
<template v-else-if="checkedValueComponents.includes(schema.component)">
<FormItem
v-if="getShow(schema)"
v-show="getIsShow(schema)"
:key="schema.key"
:label="getComponentsProps.showLabel ? schema.label : ''"
:label-col="labelCol"
:name="schema.field"
:rules="rules"
:wrapperCol="itemLabelWidthProp.wrapperCol"
>
<component
:is="componentMap.get(schema.component)"
:key="refreshFieldObj[schema.field]"
v-model:checked="formModel![schema.field]"
:disabled="getDisable"
:size="formProps?.size"
v-bind="getComponentsProps"
/>
<FormItem v-if="getShow(schema)" v-show="getIsShow(schema)" :key="schema.key" :label="getComponentsProps.showLabel ? schema.label : ''" :label-col="labelCol" :name="schema.field" :rules="rules" :wrapperCol="itemLabelWidthProp.wrapperCol">
<component :is="componentMap.get(schema.component)" :key="refreshFieldObj[schema.field]" v-model:checked="formModel![schema.field]" :disabled="getDisable" :size="formProps?.size" v-bind="getComponentsProps" />
</FormItem>
</template>
<!--如果是card 组件 需要新增card组件包裹-->
<template v-else-if="schema.component.includes('Card')">
<CollapseContainer
v-show="getIsShow(schema)"
:bordered="false"
:hasLeftBorder="true"
:title="(schema.componentProps as any ).title"
>
<CollapseContainer v-show="getIsShow(schema)" :bordered="false" :hasLeftBorder="true" :title="(schema.componentProps as any ).title">
<template v-for="childSchema in schema.children![0].list" :key="childSchema.field">
<SimpleFormItem
v-if="showComponent(childSchema)"
v-model:value="formModel![childSchema.field]"
:form-api="formApi"
:isWorkFlow="isWorkFlow"
:refreshFieldObj="refreshFieldObj"
:schema="childSchema"
/>
<SimpleFormItem v-if="showComponent(childSchema)" v-model:value="formModel![childSchema.field]" :form-api="formApi" :isWorkFlow="isWorkFlow" :refreshFieldObj="refreshFieldObj" :schema="childSchema" />
</template>
</CollapseContainer>
</template>
@ -227,14 +134,7 @@
:validateTrigger="['blur', 'change']"
:wrapperCol="itemLabelWidthProp.wrapperCol"
>
<component
:is="componentMap.get(schema.component)"
:key="refreshFieldObj[schema.field]"
:disabled="getDisable"
:size="formProps?.size"
:value="schema.defaultValue"
v-bind="getComponentsProps"
/>
<component :is="componentMap.get(schema.component)" :key="refreshFieldObj[schema.field]" :disabled="getDisable" :size="formProps?.size" :value="schema.defaultValue" v-bind="getComponentsProps" />
</FormItem>
</template>
<template v-else>
@ -249,20 +149,11 @@
:validateTrigger="['blur', 'change']"
:wrapperCol="itemLabelWidthProp.wrapperCol"
>
<template
v-if="getDisable && /Input|AutoCodeRule|DatePicker/.test(schema.component)"
>
<template v-if="getDisable && /Input|AutoCodeRule|DatePicker/.test(schema.component)">
<readonly :schema="schema" :value="formModel![schema.field]" />
</template>
<template v-else>
<component
:is="defaultComponent(schema)"
:key="refreshFieldObj[schema.field]"
v-model:value="formModel![schema.field]"
:disabled="getDisable"
:size="formProps?.size"
v-bind="getComponentsProps"
/>
<component :is="defaultComponent(schema)" :key="refreshFieldObj[schema.field]" v-model:value="formModel![schema.field]" :disabled="getDisable" :size="formProps?.size" v-bind="getComponentsProps" />
</template>
</FormItem>
</template>
@ -277,10 +168,7 @@
import { useItemLabelWidth } from '/@/components/Form/src/hooks/useLabelWidth';
import { FormActionType, FormProps, FormSchema } from '/@/components/Form/src/types/form';
import { CollapseContainer } from '/@/components/Container';
import {
noShowWorkFlowComponents,
noShowGenerateComponents,
} from '/@/components/Form/src/helper';
import { noShowWorkFlowComponents, noShowGenerateComponents } from '/@/components/Form/src/helper';
import { useMessage } from '/@/hooks/web/useMessage';
import TableLayoutPreview from '/@/components/Form/src/components/TableLayoutPreview.vue';
import { camelCaseString } from '/@/utils/event/design';
@ -292,22 +180,22 @@
// 表单配置规则
schema: {
type: Object as PropType<FormSchema>,
default: () => {},
default: () => {}
},
value: [Object, String, Number, Boolean, Array],
formApi: {
type: Object as PropType<FormActionType>,
type: Object as PropType<FormActionType>
},
//刷新api使用
refreshFieldObj: {
type: Object,
default: () => {},
default: () => {}
},
//是否是工作流
isWorkFlow: {
type: Boolean,
default: false,
},
default: false
}
});
const formModel = inject<Recordable>('formModel');
@ -315,14 +203,16 @@
const tabActiveKey = inject<Ref<number>>('tabActiveKey', ref(0));
const activeKey = ref<number>(0);
const isCamelCase = inject<boolean>('isCamelCase', false);
// 注入整个表单的配置formProps是个计算属性不能修改formData则来自每个业务的表单页面。
const formData = inject('formData', { noInject: true });
watch(
() => tabActiveKey?.value,
(val) => {
if (props.isWorkFlow) activeKey.value = val!;
},
{
immediate: true,
},
immediate: true
}
);
watch(
() => activeKey?.value,
@ -330,8 +220,8 @@
if (props.isWorkFlow) tabActiveKey.value = val!;
},
{
immediate: true,
},
immediate: true
}
);
// watch(
@ -381,7 +271,7 @@
values: formModel![getSchema.value.field],
model: formModel!,
schema: unref(getSchema),
field: unref(getSchema).field,
field: unref(getSchema).field
});
}
return disabled;
@ -395,38 +285,31 @@
componentProps({
schema: props.schema,
formModel,
formActionType: props.formApi,
formActionType: props.formApi
}) ?? {};
} else {
if (componentProps['events']) {
for (const eventKey in componentProps['events']) {
try {
const event = new Function(
'schema',
'formModel',
'formActionType',
`${componentProps['events'][eventKey]}`,
);
const fun = componentProps['events'][eventKey];
let event;
if (typeof fun === 'string') {
event = new Function('schema', 'formModel', 'formActionType', 'extParams', `${fun}`);
} else if (typeof fun === 'function') {
event = fun;
}
componentProps['on' + upperFirst(eventKey)] = function () {
let cloneFormModel = cloneDeep(formModel);
for (let item in cloneFormModel) {
let field = camelCaseString(item);
if (field) cloneFormModel[field] = cloneFormModel[item];
}
event(
props.schema,
isCamelCase ? cloneFormModel : formModel,
props.formApi,
);
event(props.schema, isCamelCase ? cloneFormModel : formModel, props.formApi, { formData });
if (isCamelCase) {
for (let item in formModel) {
let field = camelCaseString(item);
if (
cloneFormModel &&
field &&
cloneFormModel[field] !== undefined
) {
if (cloneFormModel && field && cloneFormModel[field] !== undefined) {
formModel[item] = cloneFormModel[field];
}
}
@ -436,7 +319,7 @@
console.log('error', error);
notification.error({
message: 'Tip',
description: '触发事件填写有误!',
description: '触发事件填写有误!'
});
}
}
@ -453,15 +336,13 @@
});
const labelCol = computed(() => {
return unref(getComponentsProps).span
? { span: unref(getComponentsProps).span }
: unref(itemLabelWidthProp).labelCol;
return unref(getComponentsProps).span ? { span: unref(getComponentsProps).span } : unref(itemLabelWidthProp).labelCol;
});
const rules = computed(() => {
const requiredRule = {
required: unref(getComponentsProps).required || false,
message: `${props.schema.label}是必填项`,
message: `${props.schema.label}是必填项`
};
const rulesList = cloneDeep(unref(getComponentsProps).rules);
if (!rulesList) return [requiredRule];
@ -477,10 +358,7 @@
// console.log('formitem watch!!!!!!!!');
//填值以后需要手动校验的组件
const validateComponents = ['User', 'RichTextEditor', 'Upload', 'SelectMap'];
if (
validateComponents.includes(props.schema.component) &&
formModel![props.schema.field]
) {
if (validateComponents.includes(props.schema.component) && formModel![props.schema.field]) {
setTimeout(() => {
props.formApi?.validateFields([props.schema.field]);
}, 100);
@ -488,8 +366,8 @@
},
{
deep: true,
immediate: true,
},
immediate: true
}
);
onMounted(() => {
// console.log('onMounted');
@ -510,31 +388,15 @@
});
const formComponent = (schema) => {
return componentMap.get(
[
'caseErpApplyDetailList',
'case_erp_apply_detailList',
'CASE_ERP_APPLY_DETAILList',
].includes(schema.field)
? 'ErpApply'
: schema.component,
);
return componentMap.get(['caseErpApplyDetailList', 'case_erp_apply_detailList', 'CASE_ERP_APPLY_DETAILList'].includes(schema.field) ? 'ErpApply' : schema.component);
};
const defaultComponent = (schema) => {
return componentMap.get(
schema.key === 'ac18952da41b45c9a66ffba3e42b7f3d'
? 'ErpUpload'
: schema.key === 'b3ba87573cf0466d951bc63fd4df1c78'
? 'ErpCheck'
: schema.component,
);
return componentMap.get(schema.key === 'ac18952da41b45c9a66ffba3e42b7f3d' ? 'ErpUpload' : schema.key === 'b3ba87573cf0466d951bc63fd4df1c78' ? 'ErpCheck' : schema.component);
};
function showComponent(schema) {
return props.isWorkFlow
? !noShowWorkFlowComponents.includes(schema.type)
: !noShowGenerateComponents.includes(schema.type);
return props.isWorkFlow ? !noShowWorkFlowComponents.includes(schema.type) : !noShowGenerateComponents.includes(schema.type);
}
function getShow(schema: FormSchema): boolean {