ant-design-vue中动态增加表单项,动态增加验证

121 阅读1分钟

有一个需求,要增加上课的时段,可以删除,必填,开始时间小于结束时间2个验证

image.png

循环的时候,要加验证的话,注意prop属性的值,如果要每一个时间段单独验证,必须写成

:prop="'parameterExtension.chargeTimes.' + index + '.endHour'"

因为我们循环的内容是ruleForm里面的parameterExtension.chargeTimes对象

使用自定义验证规则,将循环的每一项domain传入验证函数:

:rules="{ required: true, validator: (rule, list, callback) => validateTime(rule, list, callback, domain), trigger: 'change' }"

代码:

<template>
  <div class="wcs-content-box">
    <a-form-model v-bind="layout" :model="editForm" :rules="rules" ref="ruleForm" layout="vertical">
      <div>
        <a-divider>
          扩展参数
          <a-button type="dashed" v-if="!editForm.parameterExtension" class="ml10" @click="addExtension">添加时段</a-button>
        </a-divider>
      </div>
      <template v-if="editForm.parameterExtension">
        <a-form-model-item v-bind="formItemLayoutWithOutLabel" class="tc">
          <a-button type="dashed" style="width: 40%" @click="toAddChargeTimes"> <a-icon type="plus" /> 添加时段</a-button>
        </a-form-model-item>

        <!-- 充电时间段设置 -->
        <template v-if="editForm.parameterExtension.chargeTimes">
          <a-form-model-item
            v-for="(domain, index) in editForm.parameterExtension.chargeTimes"
            v-bind="timeLayout"
            :key="`${index}-${domain.key}`"
            label="时段"
            :prop="'parameterExtension.chargeTimes.' + index + '.endHour'"
            :rules="{ required: true, validator: (rule, list, callback) => validateTime(rule, list, callback, domain), trigger: 'change' }"
            style="margin-bottom: 10px; width: 80%; text-align: center"
          >
            <a-time-picker
              format="HH:mm"
              style="margin: 0 10px; top: -5px"
              @change="(value) => timeChange(value, index, 'start')"
              :default-value="moment(`${domain.startHour}:${domain.startMinute}`, 'HH:mm')"
            />
            ~
            <a-time-picker
              format="HH:mm"
              style="margin: 0 10px; top: -5px"
              @change="(value) => timeChange(value, index, 'end')"
              :default-value="moment(`${domain.endHour}:${domain.endMinute}`, 'HH:mm')"
              :disabledHours="() => disabledHours(index)"
              :disabledMinutes="(selectedHour) => disabledMinutes(selectedHour, index)"
            />
            <a-icon type="minus-circle-o" @click="removeDomain(domain)" />
          </a-form-model-item>
        </template>
      </template>

      <div style="text-align: center">
        <a-button type="" @click="cancelEditForm">取消 </a-button>
        <a-button type="primary" :loading="btnLoading" class="ml10" @click="submitEditForm">提交 </a-button>
      </div>
    </a-form-model>
  </div>
</template>
<script>
import moment from "moment";
var _ = require("lodash");

export default {
  data() {
    return {
      rules: {},

      layout: {
        labelCol: { span: 11 },
        wrapperCol: { span: 13 },
      },
      timeLayout: {
        labelCol: { span: 4 },
        wrapperCol: { span: 20 },
      },
      editForm: {},
      formItemLayoutWithOutLabel: {
        wrapperCol: {
          xs: { span: 24, offset: 0 },
          sm: { span: 24, offset: 0 },
        },
      },
      btnLoading: false,
    };
  },
  methods: {
    addExtension() {
      this.$set(this.editForm, "parameterExtension", { chargeTimes: [] });
    },

    toAddChargeTimes() {
      this.editForm.parameterExtension.chargeTimes.push({
        startHour: 0,
        endHour: 0,
        startMinute: 0,
        endMinute: 0,
        key: Date.now(), // 用做for循环的key
      });
    },

    removeDomain(item) {
      let index = this.editForm.parameterExtension.chargeTimes.indexOf(item);
      if (index !== -1) {
        this.editForm.parameterExtension.chargeTimes.splice(index, 1);
      }
    },

    disabledHours(index) {
      const startHour = this.editForm.parameterExtension.chargeTimes[index].startHour;
      const hours = [];
      for (let i = 0; i < 24; i++) {
        if (i < startHour) {
          hours.push(i);
        }
      }
      return hours;
    },

    disabledMinutes(selectedHour, index) {
      const { startHour, startMinute } = this.editForm.parameterExtension.chargeTimes[index];
      const minutesList = [];
      if (selectedHour == startHour) {
        for (let i = 0; i < 60; i++) {
          if (i < startMinute) {
            minutesList.push(i);
          }
        }
      }
      return minutesList;
    },

    validateTime(rule, list, callback, domain) {
      const { startHour, startMinute, endHour, endMinute } = domain;
      const start = moment().hour(startHour).minute(startMinute).valueOf();
      const end = moment().hour(endHour).minute(endMinute).valueOf();
      if ((endHour == 0 && endMinute == 0) || (isNaN(endHour) && isNaN(endMinute)) || (isNaN(startHour) && isNaN(startMinute))) {
        callback(new Error("选择上课时间"));
      } else if (start - end > 0) {
        callback(new Error("开始时间必须早于结束时间"));
      } else {
        callback();
      }
    },

    timeChange(value, index, type) {
      const hours = moment(value).hours();
      const minutes = moment(value).minutes();
      if (type == "start") {
        this.editForm.parameterExtension.chargeTimes[index].startHour = hours;
        this.editForm.parameterExtension.chargeTimes[index].startMinute = minutes;
      } else if (type == "end") {
        this.editForm.parameterExtension.chargeTimes[index].endHour = hours;
        this.editForm.parameterExtension.chargeTimes[index].endMinute = minutes;
      }
    },

    submitEditForm() {
      this.$refs.ruleForm.validate(async (valid) => {
        if (valid) {
          console.log(valid);
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },

    cancelEditForm() {
      this.$refs.ruleForm.resetFields();
    },
    moment,
  },
};
</script>

参考:article.juejin.cn/post/701242…