diff --git a/src/calendar/index.js b/src/calendar/index.js index 478d84b75..e883c9780 100644 --- a/src/calendar/index.js +++ b/src/calendar/index.js @@ -1,26 +1,77 @@ import { createNamespace } from '../utils'; import { isDate } from '../utils/validate/date'; +import { compareMonth } from './utils'; const [createComponent, bem, t] = createNamespace('calendar'); -const now = new Date(); + +function formatMonthTitle(date) { + return t('monthTitle', date.getFullYear(), date.getMonth() + 1); +} + +function getDays(date) { + const days = []; + const cursor = new Date(date); + const placeholderCount = cursor.getDay() === 0 ? 6 : cursor.getDay() - 1; + + for (let i = 1; i <= placeholderCount; i++) { + days.push({ day: '' }); + } + + do { + days.push({ + day: cursor.getDate(), + date: new Date(cursor) + }); + + cursor.setDate(cursor.getDate() + 1); + } while (compareMonth(cursor, date) === 0); + + return days; +} export default createComponent({ props: { title: String, minDate: { type: Date, - default: () => new Date(now), + default: () => new Date(), validator: isDate }, maxDate: { type: Date, - default: () => new Date(now.getFullYear(), now.getMonth() + 6, now.getDate()), + default: () => { + const now = new Date(); + return new Date(now.getFullYear(), now.getMonth() + 6, now.getDate()); + }, validator: isDate } }, data() { - return {}; + return { + currentDate: this.minDate + }; + }, + + computed: { + months() { + const months = []; + const { minDate, maxDate } = this; + + const cursor = new Date(minDate); + cursor.setDate(1); + + do { + months.push({ + date: new Date(cursor), + days: getDays(cursor) + }); + + cursor.setMonth(cursor.getMonth() + 1); + } while (compareMonth(cursor, maxDate) !== 1); + + return months; + } }, methods: { @@ -42,15 +93,35 @@ export default createComponent({ ); }, - genMonth() {} + genMonthTitle(date) { + return
{formatMonthTitle(date)}
; + }, + + genMonth(monthItem, index) { + const Title = index !== 0 ? this.genMonthTitle(monthItem.date) : null; + + return ( +
+ {Title} +
+ {monthItem.days.map(dayItem => ( +
{dayItem.day}
+ ))} +
+
+ ); + } }, render() { return (
- {this.genTitle()} - {this.genWeekDays()} -
+
+ {this.genTitle()} + {this.genMonthTitle(this.currentDate)} + {this.genWeekDays()} +
+
{this.months.map(this.genMonth)}
); } diff --git a/src/calendar/index.less b/src/calendar/index.less index ef52ca793..a807fef9d 100644 --- a/src/calendar/index.less +++ b/src/calendar/index.less @@ -5,17 +5,25 @@ flex-direction: column; height: 80vh; - &__title, - &__weekdays { + &__header { flex-shrink: 0; + box-shadow: 0 2px 10px rgba(125, 126, 128, .16); + } + + &__title, + &__month-title { + height: 44px; + font-weight: @font-weight-bold; + line-height: 44px; + text-align: center; } &__title { - height: 44px; - font-weight: @font-weight-bold; font-size: @font-size-lg; - line-height: 44px; - text-align: center; + } + + &__month-title { + font-size: @font-size-md; } &__weekdays { @@ -34,4 +42,18 @@ overflow: auto; -webkit-overflow-scrolling: touch; } + + &__days { + display: flex; + flex-wrap: wrap; + } + + &__day { + display: flex; + align-items: center; + justify-content: center; + width: 14.285%; + height: 64px; + font-size: @font-size-lg; + } } diff --git a/src/calendar/utils.ts b/src/calendar/utils.ts new file mode 100644 index 000000000..d140cc05e --- /dev/null +++ b/src/calendar/utils.ts @@ -0,0 +1,12 @@ +export function compareMonth(date1: Date, date2: Date) { + const year1 = date1.getFullYear(); + const year2 = date2.getFullYear(); + const month1 = date1.getMonth(); + const month2 = date2.getMonth(); + + if (year1 === year2) { + return month1 === month2 ? 0 : month1 > month2 ? 1 : -1; + } + + return year1 > year2 ? 1 : -1; +} diff --git a/src/locale/lang/zh-CN.ts b/src/locale/lang/zh-CN.ts index 4ac93a0b1..9722f2149 100644 --- a/src/locale/lang/zh-CN.ts +++ b/src/locale/lang/zh-CN.ts @@ -12,7 +12,8 @@ export default { confirmDelete: '确定要删除么', telInvalid: '请填写正确的电话', vanCalendar: { - weekdays: ['日', '一', '二', '三', '四', '五', '六'] + weekdays: ['日', '一', '二', '三', '四', '五', '六'], + monthTitle: (year: number, month: number) => `${year}年${month}月` }, vanContactCard: { addText: '添加联系人'