⭐️ 写业务过程中,遇到一个需求是不可以选择同一天的时间,比如 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
}
}
}