天天看點

頁面動态循環多個form表單,并校驗非空,以及大小限制

重點:
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();
};
           

繼續閱讀