首先看效果:
把日程通过蓝色标记点标记出来,可展开收起日历。展开为月视图,收起为月-周视图,且把日程展示在日历下面。
涉及功能点有:
- 日历头部自定义
- 头部星期格式修改
- 主体样式修改
- 日程自定义
- 展开收起展示不同视图(月、月-周)
视图模式
type CalendarViewType = 'dayGridMonth' | 'dayGridWeek';
使用上面两种视图模型进行切换即可,展示为周视图时,固定高度。
核心代码
import {
CalendarApi,
CalendarOptions,
EventContentArg,
DateSelectArg,
DayHeaderContentArg,
} from '@fullcalendar/core';
import FullCalendar from '@fullcalendar/vue';
import dayGridPlugin from '@fullcalendar/daygrid';
import interactionPlugin from '@fullcalendar/interaction';
const calendarOptions = reactive<CalendarOptions>({
plugins: [dayGridPlugin, interactionPlugin],
locale: i18n.locale,
headerToolbar: false,
editable: props.editable, // 是否能编辑日期范围
dayMaxEvents: false, // 是否显示更多按钮
select: handleDateSelect,
eventResize (arg) {
arg.revert();
},
events: [],
views: {
dayGridWeek: {
type: 'dayGrid',
duration: { weeks: 1 },
},
dayGridMonth: {
dayCellContent (item) {
const date = moment(item.date).format('YYYY-M-D').split('-');
const lDate = converter.solar2lunar(date[0], date[1], date[2]);
return {
html: `<div class="${prefixCls}-day">
<label>${lDate.cDay}</label>
<span>${
lDate.IDayCn +
(lDate.lunarFestival ? ` ${lDate.lunarFestival}` : '')
}</span>
</div>`,
};
},
},
},
});
// 日期单元格重写
const dayCellContentSlot = (item) => {
const date = moment(item.date).format('YYYY-M-D').split('-');
const lDate = converter.solar2lunar(date[0], date[1], date[2]);
let LunarTag;
if (props.lunar) {
let dayText;
if (props.lunarTerm) {
dayText = lDate.Term;
}
if (props.lunarFestival && !lDate.lunarFestival?.includes('小年')) {
dayText = lDate.lunarFestival;
}
const textClass = dayText ? 'festival' : '';
LunarTag = <span class={textClass}>{dayText || lDate.IDayCn}</span>;
}
const todayTag = <div class={`${prefixCls}-day`}>
<div class={`${prefixCls}-day-todaybox`}>
<p class={`${prefixCls}-day-today`}>
<label class={`${prefixCls}-day-label`}>{lDate.cDay}</label>
{LunarTag}
</p>
</div>
</div>;
const dayTag = <div class={`${prefixCls}-day`}>
<label class={`${prefixCls}-day-label`}>{lDate.cDay}</label>
{LunarTag}
</div>;
return item.isToday ? todayTag : dayTag;
};
// 日程标记
const eventContentSlot = (arg: EventContentArg) => {
const { isToday } = arg;
return isToday ? '' : <a-badge status="processing"/>;
};
// 头部星期简化为:【日,六,五,四,三,二,一】
const dayHeaderContent = (arg: DayHeaderContentArg) => {
const textArr = arg.text.split('');
return <span class={prefixCls + '__cell-header-text'}>{textArr[textArr.length - 1]}</span>;
};
<FullCalendar
ref={fullCalendarRef}
options={calendarOptions}
scopedSlots={{
eventContent: eventContentSlot,
dayCellContent: dayCellContentSlot,
dayHeaderContent: dayHeaderContent,
}}
/>
dayGridMonth 处理农历节日 eventContentSlot重写事件 dayCellContentSlot 重写日期单元格 dayHeaderContent 重写星期格式
展开收起
// 展开收起日历
const handleCollapse = () => {
expand.value = !expand.value;
const boxElem = el.value;
if (expand.value) {
viewTypeChange('dayGridMonth'); // 修改视图类型
handleToDateAndSelect(curDate.value); // 跳转指定日期并选中
boxElem.style.height = '100%'; // 设置容器高度
} else {
viewTypeChange('dayGridWeek'); // 修改视图类型
handleToDateAndSelect(curDate.value); // 跳转指定日期并选中
boxElem.style.height = '122px'; // 设置容器高度【周只显示一行】
}
};
通过修改视图类型和修改容器高度来实现