重点:
1、父组件传动态渲染的表单数组给子组件
2、动态表单校验在子组件触发校验,把触发校验的方法暴露给父组件,在父组件提交表单的时候,调用子组件的方法
页面动态循环多个form表单,并校验非空,以及大小限制 父组件模块代码
<template>
<el-card>
<el-form
ref="formTop"
:model="_form"
label-width="150px"
:inline="true"
:rules="formTopRule"
>
<el-form-item :label="t('Upper_Keyin_Limt')" prop="upperKeyinValue">
<el-input-number v-model="_form.upperKeyinValue" :controls="false" />
</el-form-item>
<el-form-item :label="t('Lower_Keyin_Limt')" prop="lowerKeyinValue">
<el-input-number v-model="_form.lowerKeyinValue" :controls="false" />
</el-form-item>
<el-form-item
style="
position: fixed;
bottom: 0;
right: 50%;
transform: translateX(-50%);
z-index: 1;
width: auto;
"
>
<div>
<el-button type="primary" @click="submitFormTop">{{
$t('options.save')
}}</el-button>
</div>
</el-form-item>
</el-form>
<el-collapse v-model="chartType.chartTypeArr" @change="handleChange">
<el-collapse-item title="Mean" name="Mean">
<formBottomArr
v-if="_form.spcChartDefaultUpdateVOList.length"
:formBottomArr="
_form.spcChartDefaultUpdateVOList.filter(
(item) => item.chartType < 5
)
"
ref="formMean"
/>
</el-collapse-item>
<el-collapse-item title="Single" name="Single">
<formBottomArr
v-if="_form.spcChartDefaultUpdateVOList.length"
:formBottomArr="
_form.spcChartDefaultUpdateVOList.filter(
(item) => item.chartType == 10 || item.chartType == 11
)
"
ref="formSingle"
/>
</el-collapse-item>
<el-collapse-item title="Count" name="Count">
<formBottomArr
v-if="_form.spcChartDefaultUpdateVOList.length"
:formBottomArr="
_form.spcChartDefaultUpdateVOList.filter(
(item) => item.chartType == 12
)
"
ref="formCount"
/>
</el-collapse-item>
</el-collapse>
</el-card>
</template>
<script lang="ts" setup>
import formBottomArr from '@/views/utility/SetChartformDefaultParameter/components/formBottomArr.vue';
import SetChartformDefaultParameter from '@/views/utility/SetChartformDefaultParameter/index.t';
import { formBottomType } from '@/types/api/group/chart';
import {
rules,
tabContentList,
} from '@/views/utility/SetChartformDefaultParameter/components/formRule';
import { getChartDefault, setChartDefault } from '@/api/group/chart';
import useLang from '@/hooks/useLang';
import { ElMessage } from 'element-plus';
import { ElForm } from 'element-plus';
const formTop = ref(ElForm);
const { t } = useLang({ ...SetChartformDefaultParameter });
const formMean: any = ref(null);//动态表单2
const formSingle: any = ref(null);//动态表单3
const formCount: any = ref(null);//动态表单4
const chartType = reactive({
chartTypeArr: ['Mean', 'Single', 'Count'],
});
const handleChange = () => {};
const submitFormTop = () => {
formTop.value.validate(async (valid: boolean) => {
if (valid) {
let flag1 = await formMean?.value?.onSave();
let flag2 = await formSingle?.value?.onSave();
let flag3 = await formCount?.value?.onSave();
if (flag1 && flag2 && flag3) {
await setChartDefault(_form);
ElMessage.success('保存成功');
} else if (!flag1) {
chartType.chartTypeArr = ['Mean'];
} else if (!flag2) {
chartType.chartTypeArr = ['Single'];
} else {
chartType.chartTypeArr = ['Count'];
}
}
});
};
const formTopRule = reactive({
...rules(),
});
let _form = reactive({
lowerKeyinValue: 4,
upperKeyinValue: 4,
spcChartDefaultUpdateVOList: [] as formBottomType[],
});
onMounted(async () => {
const resData = await getChartDefault();
_form = Object.assign(_form, {
lowerKeyinValue: resData.data.lowerKeyinValue,
upperKeyinValue: resData.data.upperKeyinValue,
spcChartDefaultUpdateVOList: resData.data.spcChartDefaultQryVOList,
});
});
</script>
<style scoped>
:deep(.el-form-item__error) {
white-space: nowrap;
}
</style>
//formBottomArr.vue
//子组件formBottomArr动态表单代码
<template>
<el-form
ref="formBottom"
:model="_form"
:rules="bottomrRules"
label-width="150px"
:inline="true"
>
<el-row :gutter="24">
<el-col :span="4" style="margin-top: 23px">
<div class="tabContent" v-for="item in labelArr.arr" :key="item.key">
{{ t(item.key) }}{{ item.value }}:
</div>
</el-col>
<el-col :span="20">
<el-row :gutter="20">
<el-col :span="6" v-for="(item, index) in _form.formBottomArr">
<div>
<span style="margin-left: 10px">{{
statusObj[item.chartType]
}}</span>
</div>
<el-form-item :prop="`formBottomArr.${index}.uplValue`">
<el-input-number
v-model="_form.formBottomArr[index].uplValue"
:controls="false"
/>
</el-form-item>
<el-form-item :prop="`formBottomArr.${index}.uslValue`">
<el-input-number
v-model="_form.formBottomArr[index].uslValue"
:controls="false"
/>
</el-form-item>
</el-col>
</el-row>
</el-col>
</el-row>
</el-form>
</template>
<script lang="ts" setup>
import chartForm from '@/views/chart/ChartForm.t';
import useLang from '@/hooks/useLang';
import { status } from '@/views/chart/chartFormRule';
import { BottomForm } from './BottomFormRule';
import { ElForm } from 'element-plus';
const formBottom = ref(ElForm);
const labelArr = reactive({
arr: [
{ key: 'Upper_Piot_Limit', value: '(UPL)' },
{ key: 'Upper_Spec_Limit', value: '(USL)' },
],
});
const { t } = useLang({ ...chartForm });
const statusObj = reactive({
...(status() as { [key: number]: string }),
});
const props = defineProps<{
formBottomArr: any;
}>();
const _form = reactive({
formBottomArr: props.formBottomArr,
});
const bottomrRules = computed(() => {
return BottomForm(props.formBottomArr);
});
const onSave = async () => {
return formBottom.value.validate((valid: boolean) => {
return valid;
});
};
defineExpose({
onSave,
});
</script>
<style scoped>
:deep(.el-checkbox) {
height: auto;
}
.tabContent {
height: 32px;
line-height: 32px;
margin: 0 0 18px;
}
</style>
表单校验文件
//BottomFormRule.ts
export function BottomForm(formBottomArr: any, form?: any) {
let rule = {} as any;
formBottomArr.forEach((item: any, index: number) => {
rule[`formBottomArr.${index}.uplValue`] = [
{
required: true,
message: '此项必填',
trigger: 'blur',
},
createRule(0, 99999999),
];
rule[`formBottomArr.${index}.uslValue`] = [
{
required: true,
message: '此项必填',
trigger: 'blur',
},
createRule(0, formBottomArr[index].uplValue),
];
});
// console.log(rule,"+rule")
return rule;
}
export const createRule = (min: number, max: number) => {
return {
validator: (rule: any, value: any, callback: any) =>
limitNumber(rule, value, callback, { min, max }),
trigger: 'blur',
};
};
export const limitNumber = (
rule: any,
value: any,
callback: any,
{ min, max }: { min?: number; max?: number }
) => {
if (min && value < min|| value == min) {
return callback(new Error(`此值不合规范`));
}
if ((max && value > max) || value == max) {
return callback(new Error(`此值不合规范`));
}
callback();
};