如何在FullCalendar多月网格视图中跳过指定月份以实现课程视图展示
如何在FullCalendar多月网格视图中跳过指定月份以实现课程视图展示
嘿,我完全懂你的需求——做一个跨两个学年、自动跳过7、8月暑假的课程日历,用FullCalendar的multiMonth视图确实得绕开默认的连续月份逻辑,毕竟它自带的duration只会按顺序算月份,不会自动跳过指定时段。
我给你一个可行的思路:放弃直接用duration,转而用visibleRange来精确控制要展示的日期范围,手动排除掉暑假月份。具体做法如下:
首先写一个辅助函数,用来计算出课程视图需要覆盖的日期区间(比如从当年9月到次年6月,刚好10个月,跳过7、8月):
// 生成课程视图的可见日期范围,自动跳过7、8月 function getCourseVisibleRange(baseDate) { const baseYear = baseDate.getFullYear(); // 定义要展示的月份(注意:FullCalendar的月份是0索引,9月对应8,6月对应5) const targetMonths = [ { year: baseYear, month: 8 }, // 当年9月 { year: baseYear, month: 9 }, // 当年10月 { year: baseYear, month: 10 }, // 当年11月 { year: baseYear, month: 11 }, // 当年12月 { year: baseYear + 1, month: 0 },// 次年1月 { year: baseYear + 1, month: 1 },// 次年2月 { year: baseYear + 1, month: 2 },// 次年3月 { year: baseYear + 1, month: 3 },// 次年4月 { year: baseYear + 1, month: 4 },// 次年5月 { year: baseYear + 1, month: 5 },// 次年6月 ]; // 视图起始日期:第一个目标月的第一天 const rangeStart = new Date(targetMonths[0].year, targetMonths[0].month, 1); // 视图结束日期:最后一个目标月的下一个月第一天(FullCalendar的end是排他的) const rangeEnd = new Date(targetMonths.at(-1).year, targetMonths.at(-1).month + 1, 1); return { start: rangeStart, end: rangeEnd }; }
接下来修改你的FullCalendar配置,把自定义视图的duration替换成visibleRange,并设置合适的初始日期:
options = <CalendarOptions>{ plugins: [multiMonthPlugin], initialView: 'customView', multiMonthMaxColumns: 6, multiMonthMinWidth: 100, headerToolbar: { center: 'dayGridMonth,customView' // 视图切换按钮 }, views: { customView: { type: 'multiMonthYear', buttonText: '课程视图', // 动态计算可见范围,支持后续切换学年的场景 visibleRange: (info) => { // 如果是首次加载,用初始日期;否则根据当前视图的起始日期计算 const baseDate = info.currentStart || new Date(new Date().getFullYear(), 8, 1); return getCourseVisibleRange(baseDate); } } }, initialDate: new Date(new Date().getFullYear(), 8, 1), // 从当年9月开始展示 }
为什么这么做?因为visibleRange可以强制FullCalendar只渲染你指定的日期区间,完全跳过7、8月。而且这个方案还支持后续扩展——比如如果需要切换到下一个学年,只需要调整baseDate的年份,函数就会自动生成对应的新范围。
另外要注意两个细节:
- FullCalendar的月份是0索引的,所以写月份的时候要减1(比如9月对应8)
visibleRange的end必须是目标最后一个月的下一个月第一天,因为FullCalendar的结束日期是排他的,这样才能完整显示最后一个月的所有日期
备注:内容来源于stack exchange,提问作者Moha Hajjami




