背景
有一些應用系統或應用功能,如日程管理、任務管理需要使用到日歷組件。雖然Element Plus也提供了日歷組件,但功能比較簡單,用來做數據展現勉強可用。但如果需要進行復雜的數據展示,以及互動操作如通過點擊添加事件,則需要做大量的二次開發。
FullCalendar是一款備受歡迎的開源日歷組件,以其強大的功能而著稱。其基礎功能不僅免費且開源,為開發者提供了極大的便利,僅有少量高級功能需要收費。然而,盡管該組件功能卓越,其文檔卻相對簡潔,導致在集成過程中需要開發者自行摸索與探索,這無疑增加了不少學習和驗證的時間成本。
為此,本專欄通過日程管理系統的真實案例,手把手帶你了解該組件的屬性和功能,通過需求導向的方式,詳細闡述FullCalendar組件的集成思路和實用解決方案。
在介紹過程中,我們將重點關注集成要點和注意事項,力求幫助開發者在集成過程中少走彎路,提供有效的避坑指南,從而提升開發效率,更好地利用這款優秀的日歷組件。
官網:https://fullcalendar.io/
環境Vue3+Element Plus+FullCalendar 6.1.11。
使用
設置主題風格
當前外觀風格與我們系統以藍色為主色調的風格不太和諧,演示頁面有諸多風格可選。
但是通過設置themeSystem屬性,不起作用,認真琢磨了下,其實官方默認就只帶了一種樣式,就是上面截圖顯示的那種暗色調,其他包括bootstrap在內的樣式,都需要額外配置。
經查看和對比,Bootstrap5的藍色色調就不錯,動手安裝吧。
pnpm install @fullcalendar/bootstrap5
pnpm install bootstrap
pnpm install bootstrap-icons
經測試,以上3個一個都不能少,然后在配置中引入:
import bootstrap5Plugin from '@fullcalendar/bootstrap5'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-icons/font/bootstrap-icons.css'
刷新頁面,效果終于出來了:
更改all-day 顯示文本
在周視圖和日視圖頂部有個全天區域,顯示為英文 all-day
通過以下屬性調整:
// 更改all-day 顯示文本
allDayText: '全天',
新增事件
我們希望日歷組件的各視圖中點擊單元格區域或拖放單元格區域,新增事件,根據點擊或拖放區域自動設置開始時間和結束時間。
默認單元格都是只讀的,需要首先配置屬性,讓其可選中,然后配置選中事件,如下:
// 是否可以選中日歷格
selectable: true,
//選中日歷格事件
select: this.selectCell
如官方所說,對于封裝的vue組件,不再區分vue的屬性props和事件event,都以鍵值對方式放在配置選項options中。
事件回調參數是1個對象,輸出log看下大致的數據結構如下:
注:這里我們集成日歷組件,是為了做日程、任務管理,因此任務與日歷組件中的事件概念等同。
從需求出發,通過日歷的方式來新增任務,主要是想拿到起止時間,從start和end兩個屬性里就可以獲取到,另外,allDay屬性和view對象中的type可能會用到。
引入新增和修改任務的頁面(修改任務后面會用到,一塊引入進來),然后在日歷組件的select事件中調用,傳入起止時間。
//選中日歷格事件
selectCell(arg) {// 轉換時間格式const startTime = this.$dateFormatter.formatUTCTime(arg.start)const endTime = this.$dateFormatter.formatUTCTime(arg.end)// 調用新增任務this.$refs.addPage.init({ startTime, endTime })
}
拖放結束后,彈出對話框,新增任務,自動填充時間,效果如下:
搞定了事件添加,接下來的重點就是事件的展示以及修改了。
加載事件
調用后端服務獲取任務清單簡單,拿到數據后,需要轉換為日歷組件需要的數據結構。
日歷組件稱之為事件event,屬性參見官網介紹https://fullcalendar.io/docs/event-parsing。
經分析,核心屬性是三個,標題、開始時間和結束時間,此外,數據標識id組件也很貼心的預置了,在點擊事件時通過該屬性調用后端服務查詢數據非常方便。
最后,需要將轉換后的數據賦值給日歷組件配置選項的events屬性。
通過下面方法來完成數據加載、數據轉換和屬性賦值。
// 加載數據
loadData() {this.$api.task.task.listWithChildren().then((res) => {this.taskList = res.dataif (res.data) {const eventArray = res.data.map((item) => {return {id: item.id,title: item.name,start: item.startTime,end: item.endTime}})this.calendarOptions.events = eventArray}})
}
刷新頁面,效果出來了
修改事件
點擊事件時,希望打開事件查看界面,如需調整也可以直接修改,這時候調用的就是任務修改頁面了。
// 事件點擊
eventClick: this.showModifyForm// 顯示修改表單
showModifyForm(arg) {this.$refs.modifyPage.init(arg.event.id)
}
效果如下: