iview实现动态表单和自定义验证时间段重叠

动态添加表单项

iview的动态添加表单很简单,只需设置好表单项为一个array,添加新项目的时候就push一个默认好的值,剩下的iview会帮你做好。

<template lang="html">
 <div class="">

    <form
      ref="formvalidate"
      :model="formvalidate"
      :rules="rulesvalidate"
      :label-width="100"
      :label-colon="true"
    >
   <formitem
    v-for="(item, index) in formvalidate.showtimedurations"
    :key="index"
    :prop="'showtimedurations[' + index + '].value'"
    :label="'显示时段' + (index + 1)"
   >
    <row>
     <timepicker
      type="timerange"
      v-model="item.value"
      placement="bottom-end"
      placeholder="选择时间段"
      style="width: 400px;"
      :disabled="isdisedit"
      ></timepicker>
     <button shape="circle" icon="md-close" @click="handleremove(index)" style="margin-left: 10px;"></button>
    </row>
   </formitem>
   <formitem style="width: 500px;" v-if="formvalidate.showtimedurations.length < 3">
    <button type="dashed" long @click="handleaddduration" icon="md-add">添加显示时段</button>
   </formitem>
   </form>
 </div>
</template>

<script>
export default {
 name: 'banner_new',
 data() {
  return {
   formvalidate: {
    showtimedurations: [{value: ['','']}]
   }
  }
 },
 methods: {
  handleaddduration() {
   this.formvalidate.showtimedurations.push({value: ['','']})
  },
  handleremove(index) {
   this.formvalidate.showtimedurations.splice(index, 1)
  }
 }
}
</script>

<style lang="css" scoped>
</style>

表单验证

iview的表单验证是通过在form添加属性 :rules="rulesvalidate" ,rulesvalidate是在methods里设置的方法。

添加一个title表单项和提交按钮

 <formitem label="名称" prop="title" style="width: 500px;">
    <input v-model="formvalidate.title" :disabled="isdisedit" :placeholder="'请输入轮播图名称(最多50个字符)'" maxlength="50" show-word-limit></input>
  </formitem>
  ...
  <row type="flex" justify="start" style="margin-top: 20px;">
    <button type="primary" style="width: 100px; margin-left: 20px;" v-if="iscansave" @click="handlesubmit('formvalidate')">保存</button>
  </row>
  methods: {
    handlesubmit(form) {
      // 调用validate方法会执行验证
      this.$refs[form].validate(validate => {
        // validate=true/false,验证成功与否
      })
    },
  }

表单验证:

rulesvalidate: {
  title: [
    {
      required: true,
      message: '请填写轮播图名称',
      trigger: 'blur'
    },
    {
      type: 'string',
      max: 50,
      message: '50个字以内,中文/字母/数字/常用字符',
      trigger: 'change'
    }
  ],

也可以写成

title: [{{ required: true, message: '请填写图片名称', trigger: 'blur'}}]

验证条件是一个数组,可以写多个。如果需要自定义验证可以在data里面定义一个验证器

data() {
  const durationvalitator = (rule, value, callback) => {
    if(this.isshowtimepicker && value.tostring() === ',') {
      callback(new error('请选择显示时间段'));
    }else if(value[0] === value[1]) {
      callback(new error('请正确选择时间段'))
    }else if(!showtimedurationsjudge(this.formvalidate.showtimevos)){
      callback(new error('时间段不可重复'))
    }else {
      callback()
    }
  };
  const durationvalidate = [{ validator: durationvalitator, trigger: 'blur' }];
  return {
    rulesvalidate: {
      'showtimedurations[0].value': durationvalidate,
      'showtimedurations[1].value': durationvalidate,
      'showtimedurations[2].value': durationvalidate,
    }
  }
}

'showtimedurations[0].value': durationvalidate, 这种写法是表示验证表单动态项目里第一个子项目的value值,如果有3个子项需要重复写3次,不知道有没有更好的写法?暂时先这样。

showtimedurationsjudge 是验证时间段重复的方法。

验证时间段是否重叠

先考虑如果是有2段时间如何验证?不考虑跨天的情况。

思考的结果是两个时间段不重叠的充要条件就是

  • 前面的一段时间(a1)的开始(start1)和结束时间(end1)都要在后面一段时间(a2)的开始时间(start2)之前
  • 后面的一段时间(a2)的开始(start2)和结束时间(end2)都要在前面一段时间(a1)的结束时间(end1)之后

满足上面条件就能保证两段时间是完全错开的。

因为控件给的时间是”00:00:00″这种格式的字符串,我引入moment这个库来把字符串转化为时间戳,时间戳可以比较大小。

const judge = (a1,a2) => {
 let result = false
  const start1 = moment(a1[0],"hh:mm:ss").valueof()
  const end1 = moment(a1[1],"hh:mm:ss").valueof()
  const start2 =moment(a2[0],"hh:mm:ss").valueof()
  const end2 = moment(a2[1],"hh:mm:ss").valueof()

  if(start1 == start2) {
    return false
  }else if(start1 > start2) {
    result = start1 > end2
  }else {
    result = end1 < start2
  }
  return result
}

如果有重叠就返回false,没有重叠返回true。在可以比较两段时间之后,如果有更多时间段,就可以用循环的办法比较,完整的代码为:

import moment from 'moment'

export const showtimedurationsjudge = (durations) => {
 let judgeresult = true
 if(durations && durations.length > 1) {
  for(let i=0;i< durations.length-1;i++){
   for(let j=i+1;j < durations.length; j++) {
       judgeresult = judgeresult && judge(durations[i].value,durations[j].value)
     }
  }
 }
 return judgeresult
}

const judge = (a1,a2) => {
 let result = false
  const start1 = moment(a1[0],"hh:mm:ss").valueof()
  const end1 = moment(a1[1],"hh:mm:ss").valueof()
  const start2 =moment(a2[0],"hh:mm:ss").valueof()
  const end2 = moment(a2[1],"hh:mm:ss").valueof()

  if(start1 == start2) {
    return false
  }else if(start1 > start2) {
    result = start1 > end2
  }else {
    result = end1 < start2
  }
  return result
}

到此这篇关于iview实现动态表单和自定义验证时间段重叠的文章就介绍到这了,更多相关iview表单验证内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

(0)
上一篇 2022年3月21日
下一篇 2022年3月21日

相关推荐