1. 程式人生 > 實用技巧 >Ant Design of Vue a-form表單效驗用法(二)

Ant Design of Vue a-form表單效驗用法(二)

Ant Design of Vue a-form表單效驗用法(二)

  (這裡新增上期的間隔效驗用法:v-if導致的表單不能效驗問題,moment時間的用法,表單回撥)

效果圖:

1、(選中週期時在選中生效時段,失去焦點後效驗:)

2、

1、(首日、最後一日、幾號 同)

2、

(這裡考慮到如果先選擇生效時段在選週期的話,採用提交表單時效驗)

HTML:

<template>
  <div class="createRules">
    <a-form :form="form" :label-col="{ span: 4 }" :wrapper-col
="{ span: 15 }" @submit="handleSubmit"> <div v-show="showVaildTypeInterval"> <a-form-item label="間隔週期" v-show="intervalShow"> <a-radio-group @change="intervalPeriod" v-decorator="['ruleVaildIntervalTime.interval', { rules: [{ required: true, message: '請選擇間隔週期!' }] }]"
> <a-radio-button value="每日">每日</a-radio-button> <a-radio-button value="每週">每週</a-radio-button> <a-radio-button value="每月">每月</a-radio-button> </a-radio-group> </a-form-item> <a-form-item label
="選擇週期" v-show="period"> <a-checkbox-group v-decorator="['ruleVaildIntervalTime.exWeekly', { rules: [{ required: weekRequired, message: '請選擇週期!' }] }]"> <a-checkbox value="週一">週一</a-checkbox> <a-checkbox value="週二">週二</a-checkbox> <a-checkbox value="週三">週三</a-checkbox> <a-checkbox value="週四">週四</a-checkbox> <a-checkbox value="週五">週五</a-checkbox> <a-checkbox value="週六">週六</a-checkbox> <a-checkbox value="週日">週日</a-checkbox> </a-checkbox-group> </a-form-item> <a-form-item label="選擇週期" v-show="periodDate"> <a-radio-group @change="periodType" v-decorator="['ruleVaildIntervalTime.exMonthly1', { rules: [{ required: monthRequired, message: '請選擇每月週期!' }] }]"> <a-radio value="首日">首日</a-radio> <a-radio value="最後一日">最後一日</a-radio> <a-radio value="幾號"></a-radio> </a-radio-group> <a-input-number :min="2" :max="30" style="width: 50px; margin-right: 8px" placeholder="N" :disabled="monthDisabled" v-decorator="['ruleVaildIntervalTime.exMonthly2', { rules: [{ required: requiredDay, message: '請輸入幾號!' }] }]"/> <label></label> </a-form-item> <a-row type="flex" align="top"> <a-col :span="6"> <a-form-item label="起止時間" v-if="endingTime" :labelCol="{span: 9}" :wrapper-col="{ span: 8 }"> <a-time-picker :open.sync="open" format="HH:mm" placeholder="開始" style="width: 80px" @change="(val,dateStrings)=>changeTime(val,dateStrings,'startTime')" v-decorator="['ruleVaildIntervalTime.exDateTimeOnt', { rules: [{ required: requiredIntervalTime, message: '請選擇開始時間!' }] }]" > <a-button slot="addon" size="small" type="primary" @click="handleClose">確定</a-button> </a-time-picker> </a-form-item> </a-col> <a-col style="height: 40px;line-height: 40px;padding: 0 2px">~</a-col> <a-col :span="10"> <a-form-item> <a-time-picker :open.sync="open2" format="HH:mm" placeholder="結束" style="width: 80px" :disabledHours="getDisabledHours" :disabledMinutes="getDisabledMinutes" @change="(val,dateStrings)=>changeTime(val,dateStrings,'endTime')" v-decorator="['ruleVaildIntervalTime.exDateTimeTwo', { rules: [{ required: requiredIntervalTime, message: '請選擇結束時間!' }] }]" > <a-button slot="addon" size="small" type="primary" @click="handleClose">確定</a-button> </a-time-picker> </a-form-item> </a-col> </a-row> <a-row> <a-col :span="6" :offset="1"> <a-form-item label="生效時段" :labelCol="{span: 9}" :wrapper-col="{ span: 12 }" > <a-select style="width: 110px;margin-right:8px" @change="allTime" v-decorator="['dayType', { rules: [{ required: true}] }]" > <a-select-option :value="0">全時段</a-select-option> <a-select-option :value="1">自定義</a-select-option> <a-select-option :value="2">非交易日</a-select-option> </a-select> </a-form-item> </a-col> <a-col :span="10"> <a-form-item> <a-range-picker format="YYYY-MM-DD" style="width: 370px" :placeholder="['開始日期', '結束日期']" :disabled="disableds" :disabled-date="handleData" v-decorator="['customTime', { rules: [{ type: 'array', required: requiredTime, message: '請選擇生效時段!' }] }]" @blur="customTimeBlur" /> </a-form-item> </a-col> </a-row> </div> </a-form> </div> </template>

JavaScritp

<script>
import moment from 'moment'
//要引用ant Design元件

export default {
  name: 'CreateRules',
  data () {
    return {
      period: true,
      periodDate: false,
      disableds: false,
      monthDisabled: true,
      intervalShow: true,
      requiredTime: true,
      requiredIntervalTime: true,
      requiredDay: true,
      endingTime: true,
      weekRequired: true,
      monthRequired: true,
      efficacyState: true,
      showVaildTypeInterval: true,
      open: false,
      open2: false,
      timeDisabled: true,
      startTime: '00:00',
      endTime: '23:59',
      alldefaultValue: '全時段',
    }
  },
  beforeCreate () {
    this.form = this.$form.createForm(this, { name: 'coordinated' })
  },
  mounted () {
    this.resetForm()
  },
  methods: {
    moment,
    handleClose () {
      this.open = false
      this.open2 = false
    },
    handleCloseContinuous () {
      this.continuousOpen = false
      this.continuousOpen2 = false
    },
    // @blur: 選中日期後失去焦點時效驗
    // 間隔 效驗頻率是否在維護時段內
    customTimeBlur (e) {
      this.form.validateFields(['ruleVaildIntervalTime.interval',
        'ruleVaildIntervalTime.exMonthly1',
        'ruleVaildIntervalTime.exMonthly2'], (errors, values) => {
        if (!errors && e.target.value) {
          this.soundEffects(e, values)
        }
      })
    },
    // 我這裡封裝好了一個方法,主要用在兩個地方:表單點選選擇效驗、表單提交時效驗(這裡表單提交時是傳一個空e)
    soundEffects (e, values) {
      console.log('生效時段效驗:', values)
      const everyDay = []
      const everyDayString = []
      const findMonthDay = []
    //   拿到開始結束時間的時間戳來對間隔型別繼續比較
    // 一天的時間戳為:86400000
      const startTime = (e === '' ? moment(moment(values.customTime[0]).valueOf()).format('YYYY-MM-DD')
        : moment(moment(e.target.value.substring(1, 33)).valueOf()).format('YYYY-MM-DD'))
      const endTime = (e === '' ? moment(moment(values.customTime[1]).valueOf()).format('YYYY-MM-DD')
        : moment(moment(e.target.value.substring(34, 67)).valueOf()).format('YYYY-MM-DD'))
      const formatStartTime = moment(startTime).valueOf() - 86400000
      const formatEndTime = moment(endTime).valueOf()
      const yearEndDay = []
      // 獲取每月最後一日(1-30 這樣的格式)
      for (let i = 0; i < 12; i++) {
        yearEndDay.push((i + 1) + '-' + moment(moment().month(i).endOf('month').format('YYYY-MM-DD')).date())
      }
      // 獲取時間戳的每天
      for (let i = formatEndTime; i > formatStartTime; i -= 86400000) {
        everyDay.push(moment(i).date())
      }
      // 通過時間戳來獲取每月最後一日 (1-30 這樣的格式)(時間戳.month()拿到的月是從0開始)
      for (let i = formatEndTime; i > formatStartTime; i -= 86400000) {
        everyDayString.push((moment(i).month() + 1) + '-' + moment(i).date())
      }
      // 通過比較上下最後一日來判斷 選中每月最後一日是否在指定的日期範圍內
      yearEndDay.forEach(res => {
        if (everyDayString.find(item => item === res) !== undefined) {
          findMonthDay.push(everyDayString.find(item => item === res))
        }
      })
      if (values.ruleVaildIntervalTime.interval === '每月') {
        if (values.ruleVaildIntervalTime.exMonthly1 === '首日' && everyDay.find(item => item === 1) === undefined ||
          values.ruleVaildIntervalTime.exMonthly1 === '幾號' &&
            everyDay.find(item => item === values.ruleVaildIntervalTime.exMonthly2) === undefined ||
          values.ruleVaildIntervalTime.exMonthly1 === '最後一日' && findMonthDay.length === 0
        ) {
          const arr = [{
            message: '維護時段不在範圍內!',
            field: 'customTime'
          }]
          this.form.setFields({ customTime: { value: [], errors: arr } })
          this.efficacyState = false
        } else {
          this.efficacyState = true
        }
      } else {
        this.efficacyState = true
      }
    
    // 這裡主要用到表單提交時效驗是否通過進行傳參
      if (this.efficacyState) {
        this.$emit('getResult2', values, true)
      } else {
        this.$emit('getResult2', values, false)
      }
    },
    // 時間約束(時分)
    changeTime (val, dateStrings, type) {
      if (type === 'startTime') {
        this.startTime = dateStrings
      } else {
        this.endTime = dateStrings
      }
    },
    getDisabledHours () {
      if (this.timeDisabled) {
        const hours = []
        const time = this.startTime
        const timeArr = time.split(':')
        for (let i = 0; i < parseInt(timeArr[0]); i++) {
          hours.push(i)
        }
        return hours
      } else {
        return []
      }
    },
    getDisabledMinutes (selectedHour) {
      if (this.timeDisabled) {
        const time = this.startTime
        const timeArr = time.split(':')
        const minutes = []
        if (selectedHour === parseInt(timeArr[0])) {
          for (let i = 0; i < parseInt(timeArr[1]) + 1; i++) {
            minutes.push(i)
          }
        }
        return minutes
      } else {
        return []
      }
    },

    handleData (current) {
      return current && current + 1 < moment().endOf('day').subtract(1, 'day')
    },
    allTime (val) {
      if (val === 0) {
        console.log('全時段')
        this.disableds = true
        this.requiredTime = false
        this.alldefaultValue = '全時段'
        // 這裡form表單提交時 資料不能為null、undefined,不然傳值的時候全部值都為空
        // this.form.resetFields('customTime', [])
        this.form.setFields({ 'customTime': { value: [] } })
      } else if (val === 1) {
        console.log('自定義')
        this.disableds = false
        this.requiredTime = true
        this.alldefaultValue = '自定義'
      } else {
        console.log('非交易日')
        this.disableds = false
        this.requiredTime = true
        this.alldefaultValue = '非交易日'
      }
    },

    resetForm () {
      this.$nextTick(() => {
        this.form.setFieldsValue({
          // 維護狀態form表繫結值,可以是一個自定義物件
          ruleVaildIntervalTime: {
              interval: '每週',
              exWeekly: ['週一', '週二', '週三', '週四', '週五', '週六', '週日'],
              exMonthly1: '',
              exMonthly2: '',
              exDateTimeOnt: moment('00:00', 'HH:mm'),
              exDateTimeTwo: moment('23:59', 'HH:mm'),
            },
          customTime: [],
          dayType: 0,
        })
      })
    },
    intervalPeriod (val) {
      if (val.target.value === '每日') {
        this.period = false
        this.periodDate = false
        this.weekRequired = false
        this.monthRequired = false
      } else if (val.target.value === '每週') {
        this.period = true
        this.periodDate = false
        this.weekRequired = true
        this.monthRequired = false
      } else if (val.target.value === '每月') {
        this.period = false
        this.periodDate = true
        this.weekRequired = false
        this.monthRequired = true
      }
    },
    periodType (val) {
      if (val.target.value === '幾號') {
        this.monthDisabled = false
        this.requiredDay = true
      } else {
        this.monthDisabled = true
        this.requiredDay = false
      }
    },

    // 提交哦(提交的話,自己自定義新增的效驗,提交時應該在效驗一次,例: this.soundEffects(e, values)這個方法)
    handleSubmit () {
      this.form.validateFields((err, values) => {
        console.log('Received values of form: ', values)
        // 這裡的提交效驗(自己自定義的效驗)我就不寫了
      })
    }

  }
}
</script>

v-if導致的表單不能效驗問題

(很多時候在操作v-if、v-show的時候會使得表單中的自動效驗未能生效)

  • 使用v-if:v-if用來切換的元素是會被銷燬的,導致了v-if內的表單項,由於在mounted時期沒有進行渲染,所以規則也沒有繫結上。
    初始化時不符合顯示條件的不會生成規則,導致後面切換條件,顯示的輸入框的校驗不會生效
  • 使用v-show:初始化時會生成所有的規則,即使隱藏了也會進行規則校驗

方法:全部改為v-show

form表單api: https://www.antdv.com/components/form-cn/#API

(表單用法差不多就這些,如果有那些看不懂或者有疑惑都有下方留言!)