先看看效果预览,分别为周、月、日安排
使用场景
添加日程之后,通过请求后端接口拿到事件和时间,然后渲染到引入的fullcalendar组件中。
注意:我实现的只有查看功能,无添加日程功能。具体想实现添加功能或者想对FullCalendar有更多了解的,可以去查看fullcalendar官方文档,附上链接fullcalendar.io/docs ,不过本人看这个文档感觉怪怪的,在实现过程中,研究这东西就花费了不少时间。。。
实现过程
- 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>