Element-UI日历组件支持时间范围以及限制选择时间跨度

2020-07-14 16:31:53 浏览数 (1)

最近项目遇到一个功能:用户只能查询最近180天的订单,而且每次只能选择7天范围的时间跨度。

类似下图所示:

解释:

最近180天很好理解,就是往前推180天。每次只能选7天,是指选择的是10号,则以10号为基准点前推6天则是4号后推6天则是16号,选择的范围则是4号到16号(还得考虑180天的限制和今天日期的限制)。

示例:

为了好测试,我们把180天的限制改为20天,其实这是两个功能:1. 时间范围为20天;2.单次时间跨度7天,我们分步实现:

1.时间范围为20天

代码语言:javascript复制
let millisecondOfDay = 1 * 24 * 60 * 60 * 1000

data:{
    pickerOptions: {
        disabledDate(time) {
          return time.getTime() > Date.now() || time.getTime() < Date.now() - 20 * millisecondOfDay
        },
    },
}

效果如下:

2.单次时间跨度7天

此时我们要借助 ElementUI 提供的另一个方法 onPick

返回选择的区间最小日期和最大日期,每次选择的时候最小日期一定会返回,最大日期不一定。

那如何借助这个日期来做时间跨度限制呢?

可以这样做,当用户点击第一下时,我们可以获得最小日期,也就以当前选择的日期为基准点,前面加6天后面加6天,包括选择的基准点正好是7天。

代码如下:

代码语言:javascript复制
let millisecondOfDay = 1 * 24 * 60 * 60 * 1000
let _minDate = 0

pickerOptions: {
    disabledDate(time) {
      if (_minDate > 0) {
        return time.getTime() > _minDate   6 * millisecondOfDay || time.getTime() < _minDate - 6 * millisecondOfDay
      }
    },
    onPick({ minDate, maxDate }) {
      _minDate = minDate.getTime()
    },
},

效果如下:

选择的是20日,前后加减6天范围就是7天了。但是此时还有2个问题:

  1. 选择的范围超过了20天的范围,比如上图的今天时间是9号,明显已经超过了限制不能选择9号之后的日期。
  2. 只要我选择一次时间跨度之后,限制就只能13天内选择(上图),若我想选择1号到4号则比较麻烦,得折腾几次,一步步的往前挪7天。

解决第一个问题:

用户选择日期时有三种情况:

左右边界的限制计算时要加上20天这个限制,也就是左边界要取20天的左边界和选择时间跨度7天的左边界中大的,右边界取今天日期和时间跨度7天的右边界中小的。代码如下:

代码语言:javascript复制
let millisecondOfDay = 1 * 24 * 60 * 60 * 1000
let _minDate = 0

pickerOptions: {
    disabledDate(time) {
      if (_minDate > 0) {
        return time.getTime() > Math.min(Date.now(), _minDate   6 * millisecondOfDay) || time.getTime() < Math.max(_minDate - 6 * millisecondOfDay, Date.now() - 20 * millisecondOfDay)
      }
    },
    onPick({ minDate, maxDate }) {
      _minDate = minDate.getTime()
    },
},

加上文章开始的20天限制的代码:

代码语言:javascript复制
let millisecondOfDay = 1 * 24 * 60 * 60 * 1000
let _minDate = 0

pickerOptions: {
    disabledDate(time) {
      // 选择一个日期时  
      if (_minDate > 0) {
        return time.getTime() > Math.min(Date.now(), _minDate   6 * millisecondOfDay) || time.getTime() < Math.max(_minDate - 6 * millisecondOfDay, Date.now() - 20 * millisecondOfDay)
      }else {
        return time.getTime() > Date.now() || time.getTime() < Date.now() - 20 * millisecondOfDay
     }
    },
    onPick({ minDate, maxDate }) {
      _minDate = minDate.getTime()
    },
},

解决第二个问题:

其实解决这个问题我们要借助 ElementUI 提供的事件方法:focus 和 blur,只要把 _minDate 重新赋值为 0 就行了,回到初始状态(只有20天的限制)

全部代码如下:

代码语言:javascript复制
<template>
  <el-date-picker
    v-model="dateRange"
    :clearable="false"
    :picker-options="pickerOptions"
    value-format="yyyy-MM-dd"
    type="daterange"
    range-separator="-"
    start-placeholder="开始日期"
    end-placeholder="结束日期"
    style="width:100%"
    @blur="handlePickerBlur"
  />
</template>
<script>
let _minDate = 0
let millisecondOfDay = 1 * 24 * 60 * 60 * 1000
const dayRange = 20

export default {
    data(){
        return {
          dateRange:[],  
          pickerOptions: {
            disabledDate(time) {
              if (_minDate > 0) {
                return time.getTime() > Math.min(Date.now(), _minDate   6 * millisecondOfDay) || time.getTime() < Math.max(_minDate - 6 * millisecondOfDay, Date.now() - dayRange * millisecondOfDay)
              } else {
                return time.getTime() > Date.now() || time.getTime() < Date.now() - dayRange * millisecondOfDay
              }
            },
            onPick({ maxDate, minDate }) {
              _minDate = minDate && new Date(minDate).getTime()
            },
          },
        }
    },
    methods:{
        handlePickerBlur(date) {
          _minDate = 0
        },
    }
}
</script>

演示地址:

https://codepen.io/ghostcode/pen/rNxvdzm

0 人点赞