最近vue项目需要写一个日历组件;
涉及到渲染数据的生成。
生成渲染数据的方法如下:
buildAllYearCalendarDayRows() {
this.allYearCalendarDayRows = [];
let allYearCalendarDayRows = [];
let year = this.calendarFilter.year;
for (let month = 1; month <= 12; month++) { // 12个月
let startOfMonth = moment(`${year}-${month}`).startOf('month');
let start = null;
if(startOfMonth.day()===0){
start = startOfMonth.subtract(1, 'day').weekday(1).subtract(1, 'day');
}else{
start = startOfMonth.weekday(1).subtract(1, 'day');
}
let monthCalendarDayRows = [];
for (let rowIndex = 0; rowIndex < 6; rowIndex++) { // 一个月6周
monthCalendarDayRows[rowIndex] = [];
for (let i = 0; i < 7; i++) { // 一周7天
start = start.add(1, 'day');
monthCalendarDayRows[rowIndex].push({dayString:start.format('DD'), dayMoment:start, isCurrentMonth: start.month() === (month-1), isWorkDay: start.day()<6})
}
}
allYearCalendarDayRows.push(monthCalendarDayRows);
}
this.$set(this, 'allYearCalendarDayRows', allYearCalendarDayRows);
}
生成的数据如下
定义组件:
Vue.component('calendar', {
template: `
<div class="el-calendar">
<div class="el-calendar__header">
<slot name="header" :month="month"></slot>
</div>
<table class="el-calendar-table" cellspacing="0" cellpadding="0">
<thead>
<th v-for="(v, k) of weeks" :key="k">{{ v }}</th>
</thead>
<tbody>
<tr v-for="(dayRow, k) of month_calendar_day_rows" :key="k">
<td v-for="(day, kk) of dayRow" :key="kk" >
<slot name="cell" :day="day">{{day}}</slot>
</td>
</tr>
</tbody>
</table>
</div>
`,
props: {
weeks: {
type: Array,
default: ['一', '二', '三', '四', '五', '六', '七']
},
month: {
type: Number,
default: 1
},
month_calendar_day_rows: {
type: Array,
default: []
},
}
})
使用
<calendar :month="index+1" :month_calendar_day_rows="monthCalendarDayRows">
<template v-slot:header="scope">
<div class="calendar-header">{{scope.month}}月</div>
</template>
<template v-slot:cell="{day}">
<div class="calendar-cell" :class="{'is-current-month':day.isCurrentMonth,'is-work-day':day.isWorkDay}">
{{day.dayString}}
</div>
</template>
</calendar>
效果