(vue项目)fullcalendar实现查看日程安排

3,630 阅读1分钟

先看看效果预览,分别为周、月、日安排 image.png

image.png

image.png

使用场景

添加日程之后,通过请求后端接口拿到事件和时间,然后渲染到引入的fullcalendar组件中。

注意:我实现的只有查看功能,无添加日程功能。具体想实现添加功能或者想对FullCalendar有更多了解的,可以去查看fullcalendar官方文档,附上链接fullcalendar.io/docs ,不过本人看这个文档感觉怪怪的,在实现过程中,研究这东西就花费了不少时间。。。

实现过程

  1. npm下载以下几个依赖
    "@fullcalendar/core": "^5.10.1",
    "@fullcalendar/daygrid": "^5.10.1",
    "@fullcalendar/vue": "^5.10.1",

2.结合下面的源码做一个简单的了解,FullCalendar通过options绑定calendarOptions, methods里面主要包括了请求后端接口拿事件数据、转换拿到的事件时间格式、点击上面一排按钮分别获取到的时间范围。

其中,组件支持的事件键名如下:

{end"2022-02-21 17:21:04"
start: "2022-02-21 16:21:04"
title: "1面面试"}

源码

<template>
    <!-- 面试官周日程 -->
    <div v-loading="fullLoading" class="calendar">
        <FullCalendar
            ref="fullCalendar"
            :options="calendarOptions"
        />
        <!-- default-view="dayGridWeek" -->
    </div>
</template>
<script>
import FullCalendar from '@fullcalendar/vue';
import dayGridPlugin from '@fullcalendar/daygrid';
import { dateList } from '../../../../api/interview/newInterview';
export default {
    name: 'Calendar',
    components: {
        FullCalendar
    },
    props: {
        interviewerId: {
            type: Number,
            required: true
        }
    },
    data() {
        return {
            calendarOptions: {
                plugins: [
                    dayGridPlugin
                    // timeGridPlugin,
                    // interactionPlugin // needed for dateClick
                ],
                initialView: 'dayGridWeek',
                // initialDate: '2021-01-15',
                isRTL: true,
                locale: 'zh-cn',
                aspectRatio: 1.65,
                displayEventTime: true, // 是否显示时间
                allDaySlot: false, // 周,日视图时,all-day 不显示
                // header: {
                //     left: 'prev,next today',
                //     center: 'title',
                //     right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
                // },
                buttonText: {
                    today: '今天',
                    month: '月',
                    week: '周',
                    day: '天'
                },
                headerToolbar: {
                    // 日历头部按钮位置
                    left: 'prev,next today',
                    center: 'title',
                    right: 'dayGridMonth,dayGridWeek,dayGridDay'
                },
                customButtons: {
                    prev: {
                        text: 'PREV',
                        click: this.handlePreBtnClick
                    },
                    next: { // this overrides the next button
                        text: 'PREV',
                        click: this.handleNextBtnClick
                    },
                    today: {
                        text: '今天',
                        click: this.handleTodayBtnClick
                    },
                    dayGridMonth: {
                        text: '月',
                        click: this.handleMonthBtnClick
                    },
                    dayGridWeek: {
                        text: '周',
                        click: this.handleWeekBtnClick
                    },
                    dayGridDay: {
                        text: '天',
                        click: this.handleDayBtnClick
                    }
                },
                titleFormat: { // will produce something like "Tuesday, September 18, 2018"
                    year: 'numeric',
                    month: 'numeric',
                    day: 'numeric'
                    // weekday: 'long'
                },
                hour12: false,
                // initialView: 'timeGridWeek',
                // initialEvents: INITIAL_EVENTS, // alternatively, use the `events` setting to fetch from a feed
                events: [],
                eventDisplay: 'list-item',
                editable: true,
                selectable: true,
                selectMirror: true,
                dayMaxEvents: true,
                weekends: true,
                slotLabelFormat: {
                    hour: '2-digit',
                    minute: '2-digit',
                    meridiem: false,
                    hour12: false // 设置时间为24小时
                },
                // select: this.handleDateSelect,
                eventClick: this.handleEventClick,
                eventsSet: this.handleEvents
                /* you can update a remote database when these fire:
                    eventAdd:
                    eventChange:
                    eventRemove:
                    */
            },
            calendarPlugins: [dayGridPlugin],
            viewTitle: '',
            fullLoading: false
        };
    },
    watch: {
        viewTitle: {
            handler: function(newVal) {
                if (newVal) {
                    this.$nextTick(() => {
                        this.getEvents(this.interviewerId);
                    });
                }
            }
        },
        interviewerId: {
            handler: function(newVal) {
                if (newVal) {
                    this.$nextTick(() => {
                        console.log(newVal);
                        this.getEvents(newVal);
                    });
                }
            },
            deep: true
        }
    },
    mounted() {
        this.viewTitle = this.$refs.fullCalendar.getApi().getCurrentData().viewTitle;
    },
    methods: {
        handleDatesRender(arg) {
            console.log(arg.currentStart);
            console.log(arg.currentEnd);
        },
        getEvents(id) {
            this.fullLoading = true;
            const params = {
                id: id,
                endTime: this.dealDate(this.viewTitle).endTime,
                startTime: this.dealDate(this.viewTitle).startTime
            };
            dateList(params).then((res) => {
                this.calendarOptions.events = res.data;
                this.fullLoading = false;
            }).catch((err) => {
                console.log(err);
                this.fullLoading = false;
            });
        },
        // 处理时间格式
        dealDate(title) {
            if (title.indexOf(' – ') === -1) {
                title = title + ' – ' + title;
            }
            var start = title.split(' – ')[0].split('/');
            var end = title.split(' – ')[1].split('/');
            for (let a = 1; a < 3; a++) {
                if (start[a].toString().length === 1) {
                    start[a] = '0' + start[a];
                }
                if (end[a].toString().length === 1) {
                    end[a] = '0' + end[a];
                }
            }
            var startTime = start[0] + '-' + start[1] + '-' + start[2] + ' 00:00:00';
            var endTime = end[0] + '-' + end[1] + '-' + end[2] + ' 24:00:00';
            const times = {
                startTime: startTime,
                endTime: endTime
            };
            return times;
        },
        // 下周
        handleNextBtnClick() {
            const calendarApi = this.$refs.fullCalendar.getApi(); // 一旦你有ref,你可以通过getApi方法得到底层的日历对象:
            calendarApi.next(); // 调用next方法
            const test = calendarApi.getCurrentData().viewTitle;
            this.viewTitle = test;
        },
        // 上周
        handlePreBtnClick() {
            const calendarApi = this.$refs.fullCalendar.getApi();
            calendarApi.prev();
            const test = calendarApi.getCurrentData().viewTitle;
            this.viewTitle = test;
        },
        // 今天
        handleTodayBtnClick() {
            const calendarApi = this.$refs.fullCalendar.getApi();
            calendarApi.today();
            const test = calendarApi.getCurrentData().viewTitle;
            this.viewTitle = test;
        },
        handleMonthBtnClick() {
            const calendarApi = this.$refs.fullCalendar.getApi();
            calendarApi.changeView('dayGridMonth');
            const test = calendarApi.getCurrentData().viewTitle;
            this.viewTitle = test;
        },
        handleWeekBtnClick() {
            const calendarApi = this.$refs.fullCalendar.getApi();
            calendarApi.changeView('dayGridWeek');
            const test = calendarApi.getCurrentData().viewTitle;
            this.viewTitle = test;
        },
        handleDayBtnClick() {
            const calendarApi = this.$refs.fullCalendar.getApi();
            calendarApi.changeView('dayGridDay');
            const test = calendarApi.getCurrentData().viewTitle;
            this.viewTitle = test;
        }
    }
};
</script>
<style lang="scss" scoped>
/* @import '~@fullcalendar/core/main.css'; */
@import '~@fullcalendar/daygrid/main.css';
@import "@/assets/styles/variables.scss";
.calendar{
    height: 276px;
    ::v-deep .fc-direction-ltr{
        max-height: 276px;
    }
    ::v-deep .fc-button-primary,::v-deep .fc-button-active{
        background-color: #ff9c1b !important;
        border-color: #ff9c1b !important;
    }
    ::v-deep .fc-button-active{
        opacity: 0.65;
    }
    ::v-deep .fc-event-title{
        text-overflow: ellipsis;
    }
    ::v-deep .fc-day-today{
        background-color: #f1f1f1;
    }
    ::v-deep .fc-daygrid-event-dot{
        border-color: #ff9c1b;
    }
    ::v-deep button{
        outline: none !important;
        box-shadow: unset !important;
    }
}
</style>