在Vue 3中使用FullCalendar打造强大日历组件

4,304 阅读4分钟

简介

有很多FullCalendar 的文章,我的项目也是通过看那些然后才写完的,感谢那些大佬的文章,我也静悄悄的写一点分享一下,写这个项目还是踩了很多坑,所以记录一下。

FullCalendar是一个功能强大的JavaScript日历组件,它支持Vue等第三方框架。在Vue 3中,我们可以通过@fullcalendar/vue3这个官方组件来集成FullCalendar的功能,从而在我们的Vue 3项目中实现日历功能。本文将详细介绍如何在Vue 3项目中安装和使用FullCalendar,以及一些常用的API和方法。

image.png

image.png

颜色是自定义的,根据新增的时候自己选择的颜色来处理,就可以在slot里面进行自己样式的处理,这样子简单方便。

安装

首先,你需要在你的Vue 3项目中安装FullCalendar及其必要的插件

  1. @fullcalendar/vue3
  2. @fullcalendar/core

如果你需要特定的视图,比如日视图、周视图等,你还需要安装对应的插件

  1. @fullcalendar/interaction
  2. @fullcalendar/daygrid
  3. @fullcalendar/timegrid
  4. @fullcalendar/list

基本使用

在你的Vue组件中,你可以这样使用FullCalendar:

<el-button-group class="ml-4" size="small">
    <el-button :type="type == 'timeGridDay' ? 'primary' : ''" @click="changeType('timeGridDay')">日</el-button>
    <el-button :type="type == 'dayGridWeek' ? 'primary' : ''" @click="changeType('dayGridWeek')">周</el-button>
    <el-button :type="type == 'dayGridMonth' ? 'primary' : ''" @click="changeType('dayGridMonth')">月</el-button>
</el-button-group>
<el-button class="ml2" type="primary" size="small" :icon="Plus" plain @click="changeAdd">新增日程</el-button>
 <FullCalendar :options="calendarCustomnOptions" ref="Tcalendar">
    <!-- 用slot展示内容-->
    <template #eventContent="arg">
        <div class="ellipsis">
            <!-- 在这里进行自己需要的字段展示处理 ,通过arg.event拿到自己的需要的字段等-->
          <div>{{arg.event}}</div>
        </div>
    </template>
</FullCalendar>
import FullCalendar from '@fullcalendar/vue3'
import dayGridPlugin from '@fullcalendar/daygrid'
import timeGridPlugin from '@fullcalendar/timegrid'
import interactionPlugin from '@fullcalendar/interaction'
import dayjs from "/@/utils/dayjs";
import { ArrowLeftBold, ArrowRightBold, Plus } from "@element-plus/icons-vue";
const Tcalendar = ref();
const type = ref("dayGridMonth"); // 默认月视图
// 根据 initialView 动态设置 dayMaxEvents
const dayMaxValEvents = computed(() => {
    switch (type.value) {
        case 'dayGridMonth':
           return 3;
        case 'dayGridWeek':
        case 'timeGridWeek':
           return 7;
        default:
           return 3; // 周日作为一周的开始
    }
});

//我需要动态设置 firstDay,所以用了computed 
const calendarCustomnOptions = computed(() => ({
    plugins: [
      dayGridPlugin,
      timeGridPlugin,
      interactionPlugin
    ],
    locale: "zh-cn",
    headerToolbar: false, // 关闭默认日历头部,采取自定义的方式切换日历视图
    editable: true, // 允许编辑表格 是否允许拖拽和调整事件大小
    droppable: true, //允许从外部拖拽进入日历
    eventDurationEditable: true, //控制时间段是否可以拖动
    eventResizableFromStart: true, //控制事件是否可以拖动
    selectable: false, // 允许用户通过单击和拖动来突出显示多个日期或时间段
    firstDay: 1, // 设置一周中显示的第一天是哪天,周日是0,周一是1,类推。
    unselectAuto: true, // 当点击页面日历以外的位置时,是否自动取消当前的选中状态
    dayMaxEvents: dayMaxValEvents.value, //在dayGrid视图中,给定日期内的最大事件数,最多能展示几个事件
    allDaySlot: true, // 关闭全天选项
    nowIndicator: true,// 当前的时间线显示,为true时当前小时那一格有个红线,并且有红三角
    weekends: true,//周末显示
    // slotDuration: '00:30:00', // 一格时间槽代表多长时间,默认00:30:00(30分钟)
    // slotLabelInterval: '00:30:00', // 设置时间段标签间隔为整天
    slotMinTime: '00:00:00',
    slotLabelFormat: {
    hour: '2-digit', // 确保小时数为两位数
    minute: '2-digit', // 确保分钟数为两位数
    meridiem: false, // 不显示上午/下午标记
    hour12: false, // 使用24小时制
    // 自定义表格的class
    dayHeaderClassNames: 'header-x',
    dayCellClassNames: 'cell-x',
    datesSet: (ev) => {
          // 当视图的日期范围被设置时触发。这可以用于处理日期变化后的逻辑。
          我是在这里进行了接口请求,日历的数据是通过请求后再填充到日历中的
        },
     moreLinkClick: (ev) => {
          // 在这里处理“更多”链接的点击事件,自带的more弹窗有点丑,我是自己重新写的弹窗,就是需要注意隐藏自带的弹窗,我没有找到关闭弹窗的参数,是通过css处理的隐藏
        },
     eventClick:(ev){
          //事件点击,我这里是点击后进行弹窗展示,根据自己的业务逻辑
         },
     viewDidMount:(ev){
         //当视图完全渲染并且 DOM 元素已经被添加到页面上时触发。 适用于需要在视图完全渲染后执行的操作,比如添加事件监听器或者对视图进行额外的 DOM 操作。
         }
    },
})


const changeType = (val) => {
    type.value = val;
    //调用 FullCalendarApi 的 changeView 方法,传入新的类型值
    FullCalendarApi.value?.changeView(type.value);
};

onMounted(() => {
	let calendarApi = Tcalendar.value.getApi()
	FullCalendarApi.value = calendarApi;
	FullCalendarApi.value.render();//刷新日历
});

常用API & 方法& 注意事项

FullCalendar提供了丰富的API和方法,以下是一些常用的:

  • eventClick:点击事件。
  • moreLinkClick:处理“更多”链接的点击事件。
  • events:渲染数据。
  • locale:设置语言,比如中文/英文。
  • @fullcalendar/interaction 如果需要拖拽点击事件等处理

更多API的方法等,请查阅官方文档:fullcalendar.io/docs#toc

踩坑日记

好像也不能算是踩坑日记,如何把请求接口返回来的数据在试图上进行展示, 默认数据的话直接通过events: 数据源 就可以展示了 但是请求的数据就不行了,,需要获取日历视图然后通过FullCalendarApi.value.view.calendar.addEvent()来追加数据,FullCalendarApi.value.view.calendar.getEvents()可以请求视图上所有已经存在的数据。

小提示

dayGridWeek 和 timeGridWeek 都可以用来展示周视图,只是两个有一点小差别 timeGridWeek 会展示视图上左侧的时间以及全天,时间存在跨天的话就会再最顶部进行展示,左侧时间轴也可以自定义,而dayGridWeek不会展示左侧时间,如下两个图所示:

image.png

image.png