From ed130bf674a8f6d0e6ecd0fded249b601d8645cc Mon Sep 17 00:00:00 2001 From: Jiewei Qian Date: Mon, 13 Aug 2018 20:10:00 +1000 Subject: [PATCH] date-picker: refactor type='dates' fix issue #12323 {month, year} table highlights all selected dates nuke selectedDates to provide cleaner data flow --- packages/date-picker/src/basic/date-table.vue | 40 +++++++++---------- .../date-picker/src/basic/month-table.vue | 3 +- packages/date-picker/src/basic/year-table.vue | 3 +- packages/date-picker/src/panel/date.vue | 21 ++++------ packages/date-picker/src/picker.vue | 16 +++----- src/utils/util.js | 26 ++++++++++++ 6 files changed, 60 insertions(+), 49 deletions(-) diff --git a/packages/date-picker/src/basic/date-table.vue b/packages/date-picker/src/basic/date-table.vue index 56018fdf7c..f145cf3f6a 100644 --- a/packages/date-picker/src/basic/date-table.vue +++ b/packages/date-picker/src/basic/date-table.vue @@ -35,6 +35,7 @@ import { getFirstDayOfMonth, getDayCountOfMonth, getWeekNumber, getStartDateOfMonth, nextDate, isDate } from '../util'; import { hasClass } from 'element-ui/src/utils/dom'; import Locale from 'element-ui/src/mixins/locale'; + import { arrayFindIndex, arrayFind, coerceTruthyValueToArray } from 'element-ui/src/utils/util'; const WEEKS = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']; const clearHours = function(time) { @@ -43,6 +44,14 @@ return cloneDate.getTime(); }; + // remove the first element that satisfies `pred` from arr + // return a new array if modification occurs + // return the original array otherwise + const removeFromArray = function(arr, pred) { + const idx = typeof pred === 'function' ? arrayFindIndex(arr, pred) : arr.indexOf(pred); + return idx >= 0 ? [...arr.slice(0, idx), ...arr.slice(idx + 1)] : arr; + }; + export default { mixins: [Locale], @@ -75,10 +84,6 @@ disabledDate: {}, - selectedDate: { - type: Array - }, - minDate: {}, maxDate: {}, @@ -135,7 +140,7 @@ const startDate = this.startDate; const disabledDate = this.disabledDate; - const selectedDate = this.selectedDate || this.value; + const selectedDate = this.selectionMode === 'dates' ? coerceTruthyValueToArray(this.value) : []; const now = clearHours(new Date()); for (let i = 0; i < 6; i++) { @@ -188,10 +193,9 @@ } } - let newDate = new Date(time); - cell.disabled = typeof disabledDate === 'function' && disabledDate(newDate); - cell.selected = Array.isArray(selectedDate) && - selectedDate.filter(date => date.toString() === newDate.toString())[0]; + let cellDate = new Date(time); + cell.disabled = typeof disabledDate === 'function' && disabledDate(cellDate); + cell.selected = arrayFind(selectedDate, date => date.getTime() === cellDate.getTime()); this.$set(row, this.showWeekNumber ? j + 1 : j, cell); } @@ -483,19 +487,11 @@ date: newDate }); } else if (selectionMode === 'dates') { - let selectedDate = this.selectedDate; - - if (!cell.selected) { - selectedDate.push(newDate); - } else { - selectedDate.forEach((date, index) => { - if (date.toString() === newDate.toString()) { - selectedDate.splice(index, 1); - } - }); - } - - this.$emit('select', selectedDate); + const value = this.value || []; + const newValue = cell.selected + ? removeFromArray(value, date => date.getTime() === newDate.getTime()) + : [...value, newDate]; + this.$emit('pick', newValue); } } } diff --git a/packages/date-picker/src/basic/month-table.vue b/packages/date-picker/src/basic/month-table.vue index d1c0e373e1..a343cb4be4 100644 --- a/packages/date-picker/src/basic/month-table.vue +++ b/packages/date-picker/src/basic/month-table.vue @@ -51,6 +51,7 @@ import Locale from 'element-ui/src/mixins/locale'; import { isDate, range, getDayCountOfMonth, nextDate } from '../util'; import { hasClass } from 'element-ui/src/utils/dom'; + import { arrayFindIndex, coerceTruthyValueToArray } from 'element-ui/src/utils/util'; const datesInMonth = (year, month) => { const numOfDays = getDayCountOfMonth(year, month); @@ -80,7 +81,7 @@ style.disabled = typeof this.disabledDate === 'function' ? datesInMonth(year, month).every(this.disabledDate) : false; - style.current = this.value.getFullYear() === year && this.value.getMonth() === month; + style.current = arrayFindIndex(coerceTruthyValueToArray(this.value), date => date.getFullYear() === year && date.getMonth() === month) >= 0; style.today = today.getFullYear() === year && today.getMonth() === month; style.default = this.defaultValue && this.defaultValue.getFullYear() === year && diff --git a/packages/date-picker/src/basic/year-table.vue b/packages/date-picker/src/basic/year-table.vue index 8bd69563ef..607aef6d22 100644 --- a/packages/date-picker/src/basic/year-table.vue +++ b/packages/date-picker/src/basic/year-table.vue @@ -46,6 +46,7 @@