实操记录——基于Fullcalendar日历组件demo

6,559 阅读3分钟

介绍👊

😃Fullcalendar是一个目前流行的日历日程处理的js组件,它功能强大,文档齐全,可定制化高,可与你的项目无缝对接,但目前文档还是英文为主,不过gym可以通过翻译(英语精通略过这句话~😂)进行浏览。

原型图

impicture_20211027_163336.png

impicture_20211027_163337.png

需求背景

开发特制预约资源页面,宏观展示资源预约情况,解决预约业务痛点。

实操流程

👉官方vue引入教程

✔安装

安装 FullCalendar 的 @fullcalendar/vue 与 3个基础模 块 @fullcalendar/interaction@fullcalendar/core 与 @fullcalendar/daygrid

npm install --save @fullcalendar/vue @fullcalendar/core @fullcalendar/daygrid @fullcalendar/interaction @fullcalendar/timegrid

后面用到什么模块就引入什么模块,这也是该组件的一大特性。相关模块功能详解可查阅文档

👉官方plugin文档链接:fullcalendar.io/docs/plugin…

✔开发

👉FullCalendar.vue

👇引入

import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
...

👇渲染

<FullCalendar calss="fullCaleadear" ref="fullCalendar" :options="calendarOptions"/>

👇主要配置

data() {
    return {
        // 预约日历FullCalendar配置
        calendarOptions: {
            plugins: [
                dayGridPlugin,
                timeGridPlugin,
                iinteractionPlugin, // needed for dataClick
                resourceTimeLinePlugin
            ],
            initialDate: new Date(),
            timeZone: 'UTC',
            slotMinTime: '00:00:00', // 开始时间
            slotMaxTime: '24:00:00', // 结束时间
            headerToolbar: false,
            selectable: true, // 是否可select拖动
            aspectRatio: 1.5,
            initialView: 'resourceTimelineDay', 视图类型
            scrollTime: xxx, 滚动条展现位置
            // 高级功能许可key,需要用到高级功能时候添加上,避免左下角出现警告提醒
            schedulerLicenseKey: 'CC-Attribution-NonCommercial-NoDerivatives',
            // 不可预约背幕设置
            businessHours: [
                {
                    daysOfWeek: [1, 2, 3, 4, 5, 6, 7],
                    startTime: this.nowHours(), // 可接受字符串或处理函数
                    endTime: '24:00'
                }
            ],
            rerenderEvents: true,
            nowIndicator: true, // 是否显示时间指示器
            now: this.nowDateHander(), // 指示器时间,可随着时间自行移动,可接受字符串或处理函数
            nowIndicatorClassNames: 'nowIndicator', // 指示器类名
            resourceAreaWidth: '20%', 高级功能配置Column宽度
            expandRows: true,
            resourceAreaColumns: [
                {
                    group: true,
                    field: 'building',
                    headerContent: '',
                    width: '60%'
                },
                {
                    filed: 'occupancy',
                    headerContent: '',
                    cellClassNames: 'fullCalendarCell'
                }
            ],
            events: [
                {
                    resourceId: xxx, // 对应resource
                    title: xxx,
                    start: xxx, // 开始时间
                    end: xxx // 结束时间
                }
            ], // 日程时间的json,初始化导入
            resources: [ // resource配置
                {
                    id: xxx,
                    building: xxx,
                    occupancy: xxx
                }
            ],
            eventStartEditable: true,
            select: (info) => { do some thing }, // 拖动,可传处理函数
            eventClick: (info) => { do some thing }, // 时间点击,可传处理函数,
        }
    }
}

👇卡点

👉卡点1: 时间显示无法做到覆盖,并且时间间存在缝隙

impicture_20211027_163338.png 如图所示,时间无法覆盖整个格子,同时右侧存在明显缝隙。

👉解决方案:

目前由于技术有限,浏览文档多次并无很好的解决方案,只能做到去除缝隙,而整个格子覆盖效果没达到:

::v-deep .fc-timeline-event {
    margin-right: 0;
}

希望后面有更好的解决方案,不知gym有没有更好建议!😃

👉卡点2: 过期时间无法预约显示背幕遮掩,但是由于fullcalendar并没有提供businessHours随着当前时间移动,故会出现下面这种情况:

impicture_20211027_163339.png

👉解决方案:

通过js原生方法,通过定时器,每隔一段时间获取时间指示器的style,动态赋值给背幕dom,达到跟随效果。但是涉及到原生,感觉并不是最佳方案,奈何组件没有提供相关api,希望之后能有更好的方案进行优化。😂

👇注意点:

gym们特别注意开发时间相关的需求时候,尽可能让后端返回时间戳,而不是utc格式!!!因为你做到后面会发现,时间和现在时间相差8小时,不断转换会很难受!!!🤷‍♂️

如果时间格式比较多,推荐引入一些js日期库,下面给gym推荐几个比较流行的:

Moment:momentjs.com/
dayjs:day.js.org/
date-fns:date-fns.org/

✨最后

写这篇仅记录自己的一次实操经历,希望对gym有所帮助,共勉~😁