我通过使用Day-Header 和Day-Cell Render Hooks 解决了我的问题。 (可从 FullCalendar 5 获得)
- 首先,我通过在 FullCalendar 中添加
visibleRange 属性来设置从最早日期到最晚日期呈现的范围:
visibleRange={{
start: startDate,
end: endDate,
}}
注意:endDate 是专有的。
- 然后我创建了一个包含所有事件日期的数组。
const eventDatesList = [];
events.forEach((event) => {
eventDatesList.push(event.start);
});
- 最后,我创建了一个回调
handleDayDidMount,它会在每次渲染Day-Header和Day-Cell时运行,并添加到Day-Header和Day-Cell对应的props中:
dayCellDidMount={(arg => handleDayDidMount(arg))}
dayHeaderDidMount={(arg => handleDayDidMount(arg))}
注意:两个道具可以使用相同的回调。
如果渲染的日期不在我们的日期列表中,我们从 dom 中删除相应的元素。
const handleDayDidMount = ({date, el}) => {
let currentDate = DateTime.fromJSDate(date).toFormat('yyyy-MM-dd')
if (!eventDatesList.includes(currentDate)) {
el.remove()
}
}
- 剩下的唯一问题是外观问题:仍然呈现所有天的宽度。
为了解决这个问题,我们可以使用 viewDidMount 属性并使用回调来动态更改控制宽度的 DOM 元素。
viewDidMount={(arg) => handleMount(arg)}
元素是div.fc-timegrid-body 和div.fc-timegrid-slots table,所以在回调中我有以下内容:
const handleMount = ({ el }) => {
// Adapt column width to number of dates present
const timegridBody = el.querySelectorAll('div.fc-timegrid-body');
const timegridSlots = el.querySelectorAll(
'div.fc-timegrid-slots table',
);
// Update width based on rendered dates number
let newWidth = eventDatesList.length * dayMinWidth;
timegridBody[0].style['min-width'] = `${newWidth}px`;
timegridSlots[0].style['min-width'] = `${newWidth}px`;
};
注意:dayMinWidth 是一个设置为day props 的变量。
等等!
如果我将来改变我的方法,我会更新这个答案。