基于React实现类似学校教师课表的FullCalendar定制需求
解决方案:教师课表调度应用需求实现
一、基于FullCalendar的适配方案
1. 移除左侧小时列
直接通过CSS隐藏FullCalendar的时间轴列,针对timeGrid视图的小时列类名是.fc-timegrid-axis,添加以下样式:
.fc-timegrid-axis { display: none !important; } /* 调整主内容区域边距,消除留白 */ .fc-timegrid-body { margin-left: 0 !important; }
2. 自定义带展开箭头的事件组件(支持长文本+独立状态)
利用FullCalendar的eventContent钩子自定义事件渲染,创建独立的可展开事件组件,每个事件的展开状态单独维护:
// 自定义可展开事件组件 const ExpandableEvent = ({ event }) => { const [isExpanded, setIsExpanded] = useState(false); return ( <div className="custom-event"> <div className="event-header" onClick={() => setIsExpanded(!isExpanded)}> <span>{event.title}</span> <span className="expand-arrow">{isExpanded ? '▼' : '▶'}</span> </div> {isExpanded && ( <div className="event-content"> {event.extendedProps.description} {/* 其他需要展示的长文本内容 */} </div> )} </div> ); }; // 在FullCalendar配置中添加eventContent <FullCalendar // 原有配置... eventContent={({ event }) => ({ domNodes: [ReactDOM.createRoot(document.createElement('div')).render(<ExpandableEvent event={event} />)] })} />
配套样式确保布局正常:
.custom-event { border: 1px solid #ddd; border-radius: 4px; margin: 4px 0; padding: 4px; background: #f5f5f5; } .event-header { display: flex; justify-content: space-between; align-items: center; cursor: pointer; } .expand-arrow { font-size: 12px; } .event-content { margin-top: 4px; padding-top: 4px; border-top: 1px solid #eee; }
3. 关闭事件堆叠,适配内容高度
- 关闭事件重叠堆叠:添加
eventOverlap: false配置 - 让事件高度自适应内容:移除固定高度限制,依赖自定义组件的内容撑开高度
- 取消时长绑定:将所有事件标记为
allDay: true,避免FullCalendar按时长分配空间
调整后的FullCalendar关键配置片段:
<FullCalendar // 原有配置... eventOverlap={false} eventDisplay="block" events={events.map(evt => ({...evt, allDay: true}))} />
二、FullCalendar无法满足时的替代方案:自定义表格布局
如果FullCalendar的限制过多,完全自定义表格布局更灵活,适配无时长堆叠的需求:
- 数据处理:从MongoDB读取事件数据后,按周、日期分组,保留
title、description、date等核心字段 - 布局实现:
- 每周一行,周一至周五各占一列
- 每个日期单元格内渲染对应事件的可展开组件
- 核心代码示例:
const WeeklySchedule = ({ weekEvents }) => { const daysOfWeek = ['周一', '周二', '周三', '周四', '周五']; return ( <table className="schedule-table"> <thead> <tr> {daysOfWeek.map(day => <th key={day}>{day}</th>)} </tr> </thead> <tbody> <tr> {daysOfWeek.map((day, idx) => { const dayEvents = weekEvents.filter(evt => evt.dayIndex === idx); return ( <td key={day}> {dayEvents.map(evt => ( <ExpandableEvent key={evt._id} event={evt} /> ))} </td> ); })} </tr> </tbody> </table> ); };
这种方案完全可控,事件的展开逻辑、样式、布局都能按需定制,数据和MongoDB的交互流程不受影响。
内容的提问来源于stack exchange,提问作者Albert Gamundi
相关产品推荐
相关产品推荐

