网络编程
位置:首页>> 网络编程>> JavaScript>> iview实现动态表单和自定义验证时间段重叠

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

作者:董志钦  发布时间:2023-07-02 17:09:28 

标签: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实现动态表单和自定义验证时间段重叠

表单验证

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 是验证时间段重复的方法。

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

验证时间段是否重叠

先考虑如果是有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
}

来源:https://segmentfault.com/a/1190000038910345

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com