欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

利用time-Picker组件如何封装一个时间范围选择组件

程序员文章站 2022-06-07 12:15:05
...

场景:

使用过ant-design组件库的人基本都知道,它的time-picker组件并不像date-picker组件那样,支持时间范围选择。

所以,这个时候就只能自己手动来封装一个了。

 

下面正式开始:

定义一些prop属性:

props: {
    // 时间显示格式
    timeFormat: {
      type: String,
      default: 'HH:mm'
    },
    // 组件绑定的值
    timeData: {
      type: Object,
      default: function () {
        return null
      }
    },
    // 如果是有多段时间选择,此变量为所有时间段的时间数据
    timeDatas: {
      type: Array,
      default: function () {
        return []
      }
    },
    // 组件是否需要禁用
    disabled: {
      type: Boolean,
      default: false
    },
    // 未选择时间时组件显示的内容
    placeholder: {
      type: Array,
      default: function () {
        return []
      }
    },
    // 开始时间和结束时间是否需要展示更宽的宽度
    wider: {
      type: Boolean,
      default: false
    }
  },

封装的组件的核心代码:

<div style="display: inline-block;">
    <a-time-picker
      :disabled="disabled"
      :style="(wider ? 'width: 165px;margin-right: 10px' : 'width: 128px;margin-right: 10px')"
      :format="timeFormat"
      :disabledHours="getDisabledBeginHours"
      :disabledMinutes="getDisabledBeginMinutes"
      :value="timeData && timeData.timeBegin ? moment(timeData.timeBegin, timeFormat) : null"
      :placeholder="placeholder[0]"
      @change="startTimeChange"></a-time-picker>
    <a-time-picker
      :style="(wider ? 'width: 165px' : 'width: 128px')"
      :disabled="disabled"
      :format="timeFormat"
      :value="timeData && timeData.timeEnd ? moment(timeData.timeEnd, timeFormat) : null"
      :placeholder="placeholder[1]"
      :disabledHours="getDisabledEndHours"
      :disabledMinutes="getDisabledEndMinutes"
      @change="endTimeChange"></a-time-picker>
  </div>

其中最关键的是如果限制时间范围不冲突,也就是开始时间一定要早于结束时间,其中包含时,分,秒;更关键的是如果是要选择一天内的多个时间段,且时间段之间不能冲突。

这里可以利用原生组件的几个方法:

利用time-Picker组件如何封装一个时间范围选择组件

这里因为只需要选择时和分,所以先只有时 分的选项进行验证。

注意: 下面代码时间对象timeData中的id是number

getDisabledBeginHours () {
      const hours = []
      // 排除当前时间段比结束时间还晚的小时
      if (this.timeData) {
        const timeArr = this.timeData.timeEnd.split(':')
        if (timeArr.length > 1) {
          for (let i = parseInt(timeArr[0]) + 1; i < 24; i++) {
            hours.push(i) // 排除比当前时间段的结束时间同一个小时下更晚的分钟
          }
        }
      }
      // 排除比前面的时间段更晚早的小时
      if (this.timeDatas) {
        const earlierTime = []
        const laterTime = []
        this.timeDatas.forEach(t => {
          if (t.id > this.timeData.id) {
            laterTime.push(t) // 获取更晚的时间段
          } else if (t.id < this.timeData.id) {
            earlierTime.push(t) // 获取更早的时间段
          }
        })
        if (earlierTime.length > 0) {
          const timeArr = earlierTime[earlierTime.length - 1].timeEnd.split(':')
          if (timeArr.length > 1) {
            for (let i = 0; i < parseInt(timeArr[0]); i++) {
              hours.push(i) // 排除比更早的最后一个时间段的结束时间的更小的小时
            }
          }
        }
        if (laterTime.length > 0) {
          const timeArr = laterTime[0].timeBegin.split(':')
          if (timeArr.length > 1) {
            for (let i = parseInt(timeArr[0]) + 1; i < 24; i++) {
              hours.push(i) // 排除比更晚的第一个时间段的开始时间的更大的小时
            }
          }
        }
      }
      return hours
    },
    getDisabledBeginMinutes (selectedHour) {
      const minutes = []
      const timeArr = this.timeData.timeEnd.split(':')
      if (timeArr.length > 1) {
        if (selectedHour === parseInt(timeArr[0])) {
          for (var i = parseInt(timeArr[1]) + 1; i < 60; i++) {
            minutes.push(i)
          }
        }
      }
      // 排除比前面的时间段更晚早的分钟
      if (this.timeDatas) {
        const earlierTime = []
        const laterTime = []
        this.timeDatas.forEach(t => {
          if (t.id > this.timeData.id) {
            laterTime.push(t) // 获取更晚的时间段
          } else if (t.id < this.timeData.id) {
            earlierTime.push(t) // 获取更早的时间段
          }
        })
        if (earlierTime.length > 0) {
          const timeArr = earlierTime[earlierTime.length - 1].timeEnd.split(':')
          if (timeArr.length > 1) {
            if (selectedHour === parseInt(timeArr[0])) {
              for (let i = 0; i < parseInt(timeArr[1]) + 1; i++) {
                minutes.push(i) // 排除比更早的最后一个时间段的结束时间同一个小时的更小的分钟
              }
            }
          }
        }
        if (laterTime.length > 0) {
          const timeArr = laterTime[0].timeBegin.split(':')
          if (timeArr.length > 1) {
            if (selectedHour === parseInt(timeArr[0])) {
              for (let i = parseInt(timeArr[1]) + 1; i < 60; i++) {
                minutes.push(i) // 排除比更晚的第一个时间段的开始时间同一个小时的更大的分钟
              }
            }
          }
        }
      }
      return minutes
    },
    getDisabledEndHours () {
      const hours = []
      // 排除当前时间段比开始时间还早的小时
      if (this.timeData) {
        const timeArr = this.timeData.timeBegin.split(':')
        if (timeArr.length > 1) {
          for (let i = 0; i < parseInt(timeArr[0]); i++) {
            hours.push(i)
          }
        }
      }
      // 排除比后面的时间段更晚的小时
      if (this.timeDatas) {
        const laterTime = []
        const earlierTime = []
        this.timeDatas.forEach(t => {
          if (t.id > this.timeData.id) {
            laterTime.push(t) // 获取更晚的时间段
          } else if (t.id < this.timeData.id) {
            earlierTime.push(t) // 获取更早的时间段
          }
        })
        if (earlierTime.length > 0) {
          const timeArr = earlierTime[earlierTime.length - 1].timeEnd.split(':')
          if (timeArr.length > 1) {
            for (let i = 0; i < parseInt(timeArr[0]); i++) {
              hours.push(i) // 排除比更早的最后一个时间段的结束时间的更小的小时
            }
          }
        }
        if (laterTime.length > 0) {
          const timeArr = laterTime[0].timeBegin.split(':')
          if (timeArr.length > 1) {
            for (let i = parseInt(timeArr[0]) + 1; i < 24; i++) {
              hours.push(i) // 排除比更晚的第一个时间段的开始时间更大的小时
            }
          }
        }
      }
      return hours
    },
    getDisabledEndMinutes (selectedHour) {
      const minutes = []
      const timeArr = this.timeData.timeBegin.split(':')
      if (timeArr.length > 1) {
        if (selectedHour === parseInt(timeArr[0])) {
          for (var i = 0; i < parseInt(timeArr[1]) + 1; i++) {
            minutes.push(i)
          }
        }
      }
      // 排除比后面的时间段更晚的分钟
      if (this.timeDatas) {
        const laterTime = []
        const earlierTime = []
        this.timeDatas.forEach(t => {
          if (t.id > this.timeData.id) {
            laterTime.push(t) // 获取更晚的时间段
          } else if (t.id < this.timeData.id) {
            earlierTime.push(t) // 获取更早的时间段
          }
        })
        if (earlierTime.length > 0) {
          const timeArr = earlierTime[earlierTime.length - 1].timeEnd.split(':')
          if (timeArr.length > 1) {
            if (selectedHour === parseInt(timeArr[0])) {
              for (let i = 0; i < parseInt(timeArr[1]); i++) {
                minutes.push(i) // 排除比更早的最后一个时间段的结束时间的同一个小时更小的分钟
              }
            }
          }
        }
        if (laterTime.length > 0) {
          const timeArr = laterTime[0].timeBegin.split(':')
          if (timeArr.length > 1) {
            if (selectedHour === parseInt(timeArr[0])) {
              for (let i = parseInt(timeArr[1]) + 1; i < 60; i++) {
                minutes.push(i) // 排除比更晚的第一个时间段的开始时间的同一个小时更大的分钟
              }
            }
          }
        }
      }
      return minutes
    },

以上四个方法分别对开始时间的时和分,结束时间的时和分的选项是否禁用进行验证和过滤。

 

最后是利用change事件,把change之后的时间传递给父组件。

startTimeChange (time, timeString) {
   this.$emit('startTimeChange', this.timeData, timeString)
},
endTimeChange (time, timeString) {
    this.$emit('endTimeChange', this.timeData, timeString)
}

以上~ 

欢迎补充