[日期选择器] 根据月份生成对应的-日历-📅

114 阅读1分钟

基本原则

  1. 行列:6 行 7 列

原因:

  1. 一个月最多 31天,举一个例子:2022-01月,该月 31天,1月1号是周六(这里默认:一周的第一天是周末)
  2. 2022-01-02 ~ 2022-01-29 共 28 格, 占据接下来的 4 行(4 * 7),最后还剩了 30、31 两天,会单独占据一行
  3. 因此共 1 + 4 + 1 = 6 行
  1. 确定 6 * 7 日历中 的 第一天

2022-01-01 是周六,  firstDayOfWeek = firstDay.week() // 6 因此需要将前面 6个位置:周末-周五 留给上个月 因此本月第一天就是 daysOfLastMonth - firstDayOfWeek

  1. 几个特殊日历
    1. 2015-02 : 02-01 是周日 image
renderCalendar: function (side) {
      //
      // Build the matrix of dates that will populate the calendar
      //
      var _calendar = side === 'left' ? this.leftCalendar : this.rightCalendar
      /**
       * 以 2022-01-22 为例,_calendar.month = moment(2022-01-22).clone().date(2)
       * _calendar.month 是一个 moment 对象, 在 updateMonthsInView 中实现:  this.leftCalendar.month = this._startDate.clone().date(2)
       *
       * daysInMonth = 31, year = 2022, month = 0, lastMonth = 11
       */
      var month = _calendar.month.month()
      var year = _calendar.month.year()
      var hour = _calendar.month.hour()
      var minute = _calendar.month.minute()
      var second = _calendar.month.second()
      // 一个月共有多少天
      var daysInMonth = moment([year, month]).daysInMonth()
      var firstDay = moment([year, month, 1])
      var lastDay = moment([year, month, daysInMonth])
      var lastMonth = moment(firstDay).subtract(1, 'month').month()
      var lastYear = moment(firstDay).subtract(1, 'month').year()
      var daysInLastMonth = moment([lastYear, lastMonth]).daysInMonth()
      var dayOfWeek = firstDay.day()

      // initialize a 6 rows x 7 columns array for the calendar
      var calendar = []
      calendar.firstDay = firstDay
      calendar.lastDay = lastDay

      for (var i = 0; i < 6; i++) {
        calendar[i] = []
      }

      // populate the calendar with date objects
      var startDay = daysInLastMonth - dayOfWeek + this.locale.firstDay + 1
      if (startDay > daysInLastMonth) { startDay -= 7 }

      if (dayOfWeek === this.locale.firstDay) { startDay = daysInLastMonth - 6 }

      var curDate = moment([lastYear, lastMonth, startDay, 12, minute, second])

      // var col, row
      for (let i = 0, col = 0, row = 0; i < 42; i++, col++, curDate = moment(curDate).add(24, 'hour')) {
        if (i > 0 && col % 7 === 0) {
          col = 0
          row++
        }
        calendar[row][col] = curDate.clone().hour(hour).minute(minute).second(second)
        curDate.hour(12)

        if (this._minDate && calendar[row][col].format('YYYY-MM-DD') === this._minDate.format('YYYY-MM-DD') && calendar[row][col].isBefore(this._minDate) && side === 'left') {
          calendar[row][col] = this._minDate.clone()
        }

        if (this._maxDate && calendar[row][col].format('YYYY-MM-DD') === this._maxDate.format('YYYY-MM-DD') && calendar[row][col].isAfter(this._maxDate) && side === 'right') {
          calendar[row][col] = this._maxDate.clone()
        }
      }

      // make the calendar object available to hoverDate/clickDate
      if (side === 'left') {
        this.leftCalendar.calendar = calendar
      } else {
        this.rightCalendar.calendar = calendar
      }
    }