element 日期选择器选择限制

⭐️ 写业务过程中,遇到一个需求是不可以选择同一天的时间,比如 2021-8-13 - 2021-8-13,知道 datePicker 里有一个 disableDate 属性,不过之前都是用在一个时间范围,比如一个月之内或者一个星期之内,查了百度半天也没有好的解决办法,最后去看了

在这里插入图片描述

⭐️ 写业务过程中,遇到一个需求是不可以选择同一天的时间,比如 2021-8-13 - 2021-8-13,知道 datePicker 里有一个 disableDate 属性,不过之前都是用在一个时间范围,比如一个月之内或者一个星期之内,查了百度半天也没有好的解决办法,最后去看了 element-ui 的源码,知道原来我们写的 disableDate 初始化的时候和第一次选择时间的时候会根据展示的日期调用相应的次数来判断是否 disabled

element-ui 源码位置:

packages/date-picker/src/basic/date-table.vue

      rows() {
        // TODO: refactory rows / getCellClasses
        const date = new Date(this.year, this.month, 1);
        let day = getFirstDayOfMonth(date); // day of first day
        const dateCountOfMonth = getDayCountOfMonth(date.getFullYear(), date.getMonth());
        const dateCountOfLastMonth = getDayCountOfMonth(date.getFullYear(), (date.getMonth() === 0 ? 11 : date.getMonth() - 1));

        day = (day === 0 ? 7 : day);

        const offset = this.offsetDay;
        const rows = this.tableRows;
        let count = 1;

        const startDate = this.startDate;
        const disabledDate = this.disabledDate;
        const cellClassName = this.cellClassName;
        const selectedDate = this.selectionMode === 'dates' ? coerceTruthyValueToArray(this.value) : [];
        const now = getDateTimestamp(new Date());

        for (let i = 0; i < 6; i++) {
          const row = rows[i];

          if (this.showWeekNumber) {
            if (!row[0]) {
              row[0] = { type: 'week', text: getWeekNumber(nextDate(startDate, i * 7 + 1)) };
            }
          }

          for (let j = 0; j < 7; j++) {
            let cell = row[this.showWeekNumber ? j + 1 : j];
            if (!cell) {
              cell = { row: i, column: j, type: 'normal', inRange: false, start: false, end: false };
            }

            cell.type = 'normal';

            const index = i * 7 + j;
            const time = nextDate(startDate, index - offset).getTime();
            cell.inRange = time >= getDateTimestamp(this.minDate) && time <= getDateTimestamp(this.maxDate);
            cell.start = this.minDate && time === getDateTimestamp(this.minDate);
            cell.end = this.maxDate && time === getDateTimestamp(this.maxDate);
            const isToday = time === now;

            if (isToday) {
              cell.type = 'today';
            }

            if (i >= 0 && i <= 1) {
              const numberOfDaysFromPreviousMonth = day + offset < 0 ? 7 + day + offset : day + offset;

              if (j + i * 7 >= numberOfDaysFromPreviousMonth) {
                cell.text = count++;
              } else {
                cell.text = dateCountOfLastMonth - (numberOfDaysFromPreviousMonth - j % 7) + 1 + i * 7;
                cell.type = 'prev-month';
              }
            } else {
              if (count <= dateCountOfMonth) {
                cell.text = count++;
              } else {
                cell.text = count++ - dateCountOfMonth;
                cell.type = 'next-month';
              }
            }

            let cellDate = new Date(time);
            // ⭐️⭐️⭐️ 这里调用 ⭐️⭐️⭐️
            cell.disabled = typeof disabledDate === 'function' && disabledDate(cellDate); 
            cell.selected = arrayFind(selectedDate, date => date.getTime() === cellDate.getTime());
            cell.customClass = typeof cellClassName === 'function' && cellClassName(cellDate);
            this.$set(row, this.showWeekNumber ? j + 1 : j, cell);
          }

          if (this.selectionMode === 'week') {
            const start = this.showWeekNumber ? 1 : 0;
            const end = this.showWeekNumber ? 7 : 6;
            const isWeekActive = this.isWeekActive(row[start + 1]);

            row[start].inRange = isWeekActive;
            row[start].start = isWeekActive;
            row[end].inRange = isWeekActive;
            row[end].end = isWeekActive;
          }
        }

        return rows;
      }

所以我们这样写就可以了

正确答案:

       pickerOptions: {
        onPick: ({ maxDate, minDate }) => {
          if (minDate && !maxDate) {
            this.timeOptionRange = minDate
          }
          if (maxDate) {
            this.timeOptionRange = null
          }
        },
        disabledDate: (time) => {
          // 获取选中时间
          let timeOptionRange = this.timeOptionRange
          if (timeOptionRange) {
            return time.getTime() === timeOptionRange.getTime()
          }
        }
     }

扩展一下——区间为两天:

在这里插入图片描述

        pickerOptions: {
        onPick: ({ maxDate, minDate }) => {
          if (minDate && !maxDate) {
            this.timeOptionRange = minDate
          }
          if (maxDate) {
            this.timeOptionRange = null
          }
        },
        disabledDate: (time) => {
          // 获取选中时间
          let timeOptionRange = this.timeOptionRange
          let dayRange = 1 * 24 * 60 * 60 * 1000
          if (timeOptionRange) {
            console.log(222)
            return time.getTime() === timeOptionRange.getTime() || time.getTime() === timeOptionRange.getTime() + dayRange || time.getTime() === timeOptionRange.getTime() - dayRange
          }
        }
      }
知秋君
上一篇 2024-08-19 19:12
下一篇 2024-08-19 18:48

相关推荐