记录--设计一个可选择不连续的时间范围的日期选择器

这篇具有很好参考价值的文章主要介绍了记录--设计一个可选择不连续的时间范围的日期选择器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

记录--设计一个可选择不连续的时间范围的日期选择器

  • npm包:sta-datepicker
  • 效果图 

记录--设计一个可选择不连续的时间范围的日期选择器

需求

普通的时间选择器要么只能单选,要么只能选范围,不可以随意选择若干个时间,同时大多数现成的时间选择器选择结束会收起来,很不方便。现在需求如下 1、可以自己控制展开收起 2、可以选择不连续的多个时间范围的日期 3、可以批量选中日期,不需要一个个点击

实现过程(分几个步骤,具体可以看源码)

1、生成一个日历

  • 顶部为固定的几个按钮,可以绑定切换年份月份的函数

  • 中间为固定的星期,一个七个

  • 底部为具体日期,由三部分组成,即:上个月底几天,这个月整个月,下个月初几天

    • 算好平年闰年,输出当前月份第一天是周几
    • 根据当前月份的第一天的星期数,计算日历要展示上个月月底的几天
    • 根据当前月份最后一天的星期数,计算日历要展示下个月月初的几天
  • 日期部分使用div遍历三个数组,左浮动或者弹性盒直接堆起来即可

  created() {
    this.trueDateBox()
  },
  methods: {
    trueDateBox() {
      if (this.date === "") {
        const date = new Date()
        this.year = date.getFullYear()
        this.updateLeapYear()
        this.month = date.getMonth() + 1
        this.day = null
      }
      this.dayScreen()
    },
    // 设置算好闰年平年
    updateLeapYear() {
      if (this.isLeapYear(this.year)) {
        this.monthDay[1] = 29
      } else {
        this.monthDay[1] = 28
      }
    },
    isLeapYear(year) {
      return year % 100 === 0 ? year % 400 === 0 : year % 4 === 0
    },
    // 日期显示
    dayScreen() {
      // 渲染上个月,第一行
      const firstDate = new Date(this.year, this.month - 1, 1)
      const firstWeek = firstDate.getDay()
      let preMonthDay = null
      if (this.month === 1) {
        preMonthDay = this.monthDay[11]
      } else {
        preMonthDay = this.monthDay[this.month - 2]
      }
      console.log("preMonthDay", this.monthDay[11], this.month)

      for (let i = 0; i < preMonthDay; i++) {
        this.previousMonth[i] = i + 1
      }
      if (firstWeek === 0) {
        this.previousMonth = this.previousMonth.slice(-7)
      } else {
        this.previousMonth = this.previousMonth.slice(-firstWeek)
        console.log(33, this.previousMonth)
      }

      // 渲染下个月, 最后一行
      const endDate = new Date(
        this.year,
        this.month - 1,
        this.monthDay[this.month - 1]
      )
      const endWeek = endDate.getDay()
      let nextMonthDay = null
      if (this.month === 12) {
        nextMonthDay = this.monthDay[0]
      } else {
        nextMonthDay = this.monthDay[this.month]
      }
      for (let i = 0; i < nextMonthDay; i++) {
        this.nextMonth[i] = i + 1
      }
      if (endWeek === 6) {
        this.nextMonth = this.nextMonth.slice(0, 7)
      } else {
        this.nextMonth = this.nextMonth.slice(0, 6 - endWeek)
      }
    },
  }

2、绑定四个固定的函数

  • 点击上一年,下一年,上个月,下个月时,需要计算跨年的情况
    // 年份的增减
    addYear() {
      this.year++
      this.updateLeapYear()
    },
    reduceYear() {
      this.year--
      this.updateLeapYear()
    },
    // 月份的增减
    addMonth() {
      this.month++
      if (this.month > 12) {
        this.month = 1
        this.addYear()
      }
    },
    reduceMonth() {
      this.month--
      if (this.month < 1) {
        this.month = 12
        this.reduceYear()
      }
    },

3、点击具体日期时,确定状态

  • 使用数组存起当前已选的日期,使用一个变量记录当前半选的日期
  • 通过一个函数isActive给每个日期绑定类名,从而在视图上显示出来,同时可以确定状态的切换
    • 如果点击了已选日期的数据,需要剔除,改为空白状态
    • 如果点击了半选态日期,则直接选中当前日期,变为已选日期
    • 如果点击了空白状态日期,则可能有两种情况,一是已存在半选态日期,等待闭合,而是不存在半选态日期,当前设置为半选
methods: {
    // 突出显示当前日期
    isActive(index) {
      const date = new Date()
      const y = date.getFullYear()
      const m = date.getMonth() + 1
      const d = date.getDate()
      const obj = {}

      if (this.year === y && this.month === m && index === d) {
        obj.today = true
      }
      const newIndexStr = index < 10 ? `0${index}` : `${index}`
      const newMonthStr = this.month < 10 ? `0${this.month}` : `${this.month}`
      const item = `${this.year}/${newMonthStr}/${newIndexStr}`
      if (item === this.partialSelect) {
        obj.active = true
      }
      if (this.selctDate.includes(item)) {
        obj.activeRange = true
      }
      return obj
    },
    selectDay(e, type) {
      const iText = e.target.innerText
      const sDate = Number(iText) < 10 ? `0${iText}` : `${iText}`
      if (type === "previousMonth") {
        if (this.month === 1) {
          this.month = 12
          this.reduceYear()
        } else {
          this.month = this.month - 1
        }
      } else if (type === "nextMonth") {
        if (this.month === 12) {
          this.month = 1
          this.addYear()
        } else {
          this.month = this.month + 1
        }
      }

      let arr = this.selctDate.map((i) => new Date(i).getTime())
      const newMonthStr = this.month < 10 ? `0${this.month}` : `${this.month}`
      const curSelectTime = `${this.year}/${newMonthStr}/${sDate}`
      const curSelectTimeStamp = new Date(curSelectTime).getTime()
      const clsName = e.target.className // 通过类名判断当前是什么状态
      if (clsName.includes("activeRange")) {
        // 点击了范围内的数据,需要剔除
        arr = arr.filter((i) => i !== curSelectTimeStamp)
      } else if (clsName.includes("active") && !clsName.includes("activeRange")) {
        // 点击了一个半选状态的日期,准备扩展范围或者单选一个
        if (this.selctDate.length) {
          const itemTime = arr[0]
          const itemTime2 = arr[arr.length - 1]
          const selectTime = curSelectTimeStamp
          if (selectTime < itemTime) {
            console.log("点击了范围之前的时间")
          } else if (selectTime > itemTime2) {
            console.log("点击了范围之后的时间")
          } else {
            console.log("点击了范围内的空白,直接加上一个")
          }
          arr = [...arr, curSelectTimeStamp]
          console.log(arr)
        } else {
          // 第一次选择日期,而且双击了,直接单独确定这个
          arr = [curSelectTimeStamp]
        }
        // 此时选择完日前了,半选的日期消费掉了,清空
        this.partialSelect = null
      } else {
        console.log("不是半选情况")

        // 即没有点击范围内,又不是半选状态,可能是已经存在一个半选,等待这个日期来闭合范围,也可能是第一次打开点击
        if (this.partialSelect) {
          // 需要和已存在的半选态日期闭合
          const itemTime = new Date(this.partialSelect).getTime()
          const itemTime2 = curSelectTimeStamp
          const timeArr = [itemTime, itemTime2].sort((a, b) => a - b) // 排序,因为不知道谁在前面
          for (let i = timeArr[0]; i <= timeArr[1]; i += 86400000) {
            arr.push(i)
          }
          // 此时确定好范围了,半选的日期消费掉了,清空
          this.partialSelect = null
        } else if (this.selctDate.length) {
          // 存在一个范围,同时点击范围外,此时设置半选
          this.day = sDate
          this.partialSelect = curSelectTime
        } else {
          // 不存在一个范围,所以是第一次点击
          this.day = sDate
          this.partialSelect = curSelectTime
        }
      }
      let filterArr = Array.from(new Set(arr))
      filterArr = filterArr.sort((a, b) => a - b)
      this.selctDate = filterArr.map((i) => this.formatTime(new Date(i)))
      this.$emit("input", this.selctDate)
      this.$emit("change", this.selctDate)
      this.day = parseInt(sDate)
    },
}

本文转载于:

https://juejin.cn/post/7240088790423863353

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 记录--设计一个可选择不连续的时间范围的日期选择器文章来源地址https://www.toymoban.com/news/detail-486472.html

到了这里,关于记录--设计一个可选择不连续的时间范围的日期选择器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • iview时间控件 动态不可选日期 可选择24小时范围内 时间往后退24小时

    起始时间 触发 on-change 方法 结束时间 options 动态设置不可选择的日期。 disabledDate(date) 内部的 date 是时间戳的形式 , return 返回的是不想要选的区间范围 注意: toLocaleDateString 获取的是年月日 toLocaleString 获取年月日时分秒 toLocaleTimeString 获取时分秒 new Date(new Date().toLocaleStri

    2024年02月11日
    浏览(31)
  • element ui的日期选择器动态设定年份,并默认显示在该年份范围的日期时间

    选中某个年份,让日期选择器只能选择该年份内的时间,并且默认显示该年份的时间(由于日期选择器默认显示为当前时间,所以需要跳转到选择的年份) 例:年份选择了2022年,那么日期选择也相应显示到2022年,对月日没有要求,月日默认显示为当前日期的月日,只是年份变

    2024年02月13日
    浏览(46)
  • element UI DatePicker 日期选择器 点击时间点可选限制范围前后十五天

    设置:picker-options=\\\"pickerOptions\\\" 然后在data里面设置 源代码

    2024年02月06日
    浏览(54)
  • element ui el-date-picker日期时间选择器 设置只能选择不大于30天时间范围

    需求:要求日期时间选择器只能选择最多32天,其他日期为不可点击状态。 日期组件type为daterange或者datetimerange都生效 通过属性picker-options html data 效果 参考链接:https://www.jianshu.com/p/2a07de981fab

    2024年02月04日
    浏览(51)
  • datePicker一个或多个日期组件,如何快捷选择多个日期(时间段)

    elementUI的组件文档中没有详细说明type=\\\"dates\\\"如何快捷选择一个时间段的日期,我们可以通过picker-options参数来设置快捷选择: 通过设置变量pickerOption的值可设置快捷选择: 其中dateFormat方法是将日期格式化,getAllDate方法是获取开始和结束日期之间的全部日期,在data中定义:

    2024年02月13日
    浏览(35)
  • element UI日期选择器固定选择范围

    项目中经常会使用到日期选择器,并且会对可选择的日期有要求,分享几个常用的,给大家作参考。 只能选择当前日期前(不包含当前日期)  只能选择当前日期前(包含当前日期) 指定日期范围(例如2022年12月1日至当前日期)

    2024年02月07日
    浏览(33)
  • antd 日期选择框增加季度预设范围

    测试同学说想要有个季度的预设选择框,方便快速选择季度的开始和结束日期。 antd 的rangepicker是支持预设的 日期选择框 DatePicker - Ant Design 实现方法很简单,按照官网示例用moment初始化一下即可 获取当前一季度的开始日期时间: moment().quarter(1).startOf(\\\'quarter\\\') 组件使用: 效果

    2024年01月25日
    浏览(38)
  • element-plus的日期选择器限定选择范围

    提示:这里可以添加本文要记录的大概内容: element-plus的日期选择器限定选择范围,由于数据的获取范围限定,需要前端处理一下日期的选择范围 提示:以下是本篇文章正文内容,下面案例可供参考 提示:这里对文章进行总结: 这里只收集我目前为止在项目的过程中遇到的

    2024年02月13日
    浏览(39)
  • Element UI DatePicker 日期范围选择动态设置禁选日期

    今天在工作时,后端提出了一个DatePicker日期范围组件的一个问题 用图描述大概就是选择开始日期 13 号后,只能选择 13 号前一周和后一周的日期,其他日期处于禁止选择状态。 先去看了下 element 的相关文档,找到了一个 当前时间日期选择器特有的选项picker-options, 传送门

    2024年02月12日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包