做后台系统时,日程、排班、会议室预约基本都会碰到。Vue 生态里的日历库不少,用途差别很大,选错了后期改起来很麻烦。先按需求分类。

四类需求对应四种方案

只选日期:只需要日期选择框,Element Plus 的 el-date-picker、Ant Design Vue 的 a-date-picker 就够,不用另引日历库。

月视图展示事件:像手机日历那样一个月格子、每格显示几条日程。这类 FullCalendar 最成熟,有官方 @fullcalendar/vue3 组件;轻量的可以看 vue-cal。

周视图和拖拽:按小时排布、拖拽调整时间。FullCalendar 的 timeGrid 插件覆盖比较完整,Schedule-X 是近两年比较活跃的新选择。

甘特式排期:多人多任务的时间轴,这不是日历而是时间轴组件,FullCalendar 不合适,可以看 dhtmlx-gantt 的封装或自己用 CSS Grid 画。

FullCalendar 接入要点

npm i @fullcalendar/vue3 @fullcalendar/daygrid @fullcalendar/timegrid @fullcalendar/interaction
const options = {
  plugins: [dayGridPlugin, interactionPlugin],
  initialView: 'dayGridMonth',
  locale: 'zh-cn',
  events: async (info, success) => {
    const res = await fetch(`/api/events?start=${info.startStr}&end=${info.endStr}`)
    success(await res.json())
  },
  dateClick(info) { console.log(info.dateStr) }
}

locale 要设成 zh-cn 并注册对应语言包,否则界面是英文。events 用函数形式能按当前视图范围拉数据,比全量拉取省很多。

容易踩的点

  • 插件按功能拆包,缺 dayGrid 或 timeGrid 对应的视图不会显示;
  • 样式文件要单独引入,Vite 不会自动注入;
  • 事件时间前后端要统一格式,混用时间戳和 ISO 字符串会差 8 小时;
  • Nuxt 这类服务端渲染环境,日历组件只在客户端渲染,用 ClientOnly 包一层。

取舍建议

只展示不交互,vue-cal 成本更低;涉及拖拽、时区、多资源,FullCalendar 配置项多但坑都有现成答案。团队没人用过的话,先跑一遍官方示例再定。