最近在客户端的日程中用到的fullcalendar的框架,记录一下!
官方文档:https://fullcalendar.io/docs
安装插件
npm install --save @fullcalendar/vue
@fullcalendar/daygrid
@fullcalendar/interaction
@fullcalendar/timegrid
@fullcalendar/timegrid
封装组件
<template>
<div class="fullCalendarapege">
<div class="top-content">
<a-row type="flex">
<a-col :span="8">
<a-checkbox-group v-model="taskSchedule" style="float: left;" @change="changeTask">
<a-row style="margin-top: 7px;margin-right: 15px;">
<a-col :span="12">
<a-checkbox value="0">任务</a-checkbox>
</a-col>
<a-col :span="12">
<a-checkbox value="1">日程</a-checkbox>
</a-col>
</a-row>
</a-checkbox-group>
<a-button shape="round" @click="todayFn" :disabled="disabledtoday" style="height:28px;font-size: 12px;margin-top: 5px;">今天 </a-button>
</a-col>
<a-col :span="11" style="line-height: 30px;color: #333333;font-size: 14px;">
<span @click="prevFn" class="icoprev">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-xiangzuo"></use>
</svg>
</span>
<span class="datattile">{{titlehearsd}}</span>
<span @click="nextFn" class="iconext">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-xiangzuo"></use>
</svg>
</span>
</a-col>
<a-col :span="5" style=" text-align: right;">
<a-radio-group v-model="viewType" @change="changeViewTypeFn(viewType)">
<a-radio-button value="timeGridWeek">周</a-radio-button>
<a-radio-button value="dayGridMonth">月</a-radio-button>
</a-radio-group>
</a-col>
</a-row>
</div>
<FullCalendar ref="fullCalendar" :options="calendarOptions"></FullCalendar>
</div>
</template>
<script>
import '@/assets/Lunar.js';
import FullCalendar from '@fullcalendar/vue'
// import { Calendar } from '@fullcalendar/core'
import dayGridPlugin from '@fullcalendar/daygrid'//日期
import interactionPlugin from '@fullcalendar/interaction'//提供事件拖放,调整大小,dateClick和可选动作的功能
import timeGridPlugin from '@fullcalendar/timegrid'//时间
import momentPlugin from '@fullcalendar/moment'//日期
import rrulePlugin from '@fullcalendar/rrule'
import calenderFormate from "@/utils/calendarnongli.js" //农历计算方法
import * as calendar from '@/utils/calendar.js'//将日期对象转换成 2020-01-01 格式的日期
import '@/assets/css/fullCalendarapege.css'
export default {
components: {
FullCalendar
},
props:{
myCalendar: { type: Boolean,default: true},
calendarEvents:{ type: Array}, //事件数据
firstday:{ type: Number},//设置一周中显示的第一天是哪天,周日是0,周一是1
taskSval:{ type: Array}
},
data() {
return {
calendar: null,
instance: null,
taskSchedule:this.taskSval,
today:calendar.getNewDate(new Date()),
viewType:'dayGridMonth',
disabledtoday:true,
year:null,
month:null,
dayInWeek:null,
ismyCalendar:this.myCalendar,
thsiWeekFirstDay:null,
thisWeekLastDay :null,
//initialDate: '2020-05-12',
calendarOptions: {
plugins: [ dayGridPlugin, interactionPlugin, timeGridPlugin, momentPlugin , rrulePlugin ],
events:[],
initialView: 'dayGridMonth',
locale: "zh-cn",
eventLimit: true, // 设置月日程,与all-day slot的最大显示数量,超过的通过弹窗显示
weekNumberCalculation:"ISO",
firstDay:this.firstday,//设置一周中显示的第一天是哪天,周日是0,周一是1
allDaySlot:false,//是否在日历上方显示all-day(全天)
allDayText : "全天", //自定义全天视图的名称
handleWindowResize:true,//是否随浏览器窗口大小变化而自动变化。
dayMaxEventRows: true,
//displayEventEnd:true,//所有视图显示结束时间
slotEventOverlap: true, // 相同时间段的多个日程视觉上是否允许重叠,默认true允许
//自定义视图
views: {
//单元格最多显示6条
timeGrid: {
dayMaxEventRows: 5
},
dayGridMonth: { //转农历
dayCellContent(item) {
let mark = sessionStorage.getItem('joinholiday')
let _date = new Date(item.date).toLocaleDateString().split('/');
let _dateF = calenderFormate.solar2lunar(_date[0], _date[1], _date[2]);
let _datelunarFestival = _dateF.lunarFestival ? _dateF.lunarFestival : ''
let datefestival = _dateF.festival ? _dateF.festival : ''
if (item.dayNumberText == mark + '日') {
return {
html: `<p style="padding-left: 4px;"><label>${_dateF.cDay}</label></p><p style="padding-left: 4px;font-size: 11px;line-height: 20px;">(<span>${_dateF.IDayCn}<b style="color: #c71010;;padding-left: 4px;">${_datelunarFestival}${datefestival}</b></span>)</p)>`
}
} else
return {
html: `<p style="padding-left: 4px;"><label>${_dateF.cDay}</label></p><p style="padding-left: 4px;font-size: 11px;line-height: 20px;">(<span>${_dateF.IDayCn}<b style="color: #c71010;;padding-left: 4px;">${_datelunarFestival}${datefestival}</b></span>)</p)>`
}
}
},
},
//dayMaxEvents:true,
moreLinkContent : function(arg) {
let args = '还有'+arg.num+'个'
return args
},
selectable: false,//允许用户通过单击并拖动来突出显示多天或多个时段。
headerToolbar: false,
slotLabelFormat: {
hour: '2-digit',
minute: '2-digit',
meridiem: false,
hour12: false, //设置时间为24小时
},
timeFormat: {agenda:'H:mm{-H:mm}',month:'H:mm'}, //日程的时间显示格式
scrollTime:"06:00:00",
maxTime:"24:00:00",
minTime:'00:00:00',
//slotDuration:'02:00:00',
editable: false, //支持Event日程拖动修改,默认false
eventStartEditable : false, //Event日程开始时间可以改变,默认true,如果是false其实就是指日程块不能随意拖动,只能上下拉伸改变他的endTime
eventDurationEditable : false, //Event日程的开始结束时间距离是否可以改变,默认true,如果是false则表示开始结束时间范围不能拉伸,只能拖拽
/**
* 事件
*/
eventDidMount: this.eventDidMount,
dateClick: this.handleDateClick,
eventClick:this.eventClick
},
timeStamp: [],// 返回一周时间的集合
currentFirstDate: new Date(),
}
},
mounted(){
this.calendarApi = this.$refs.fullCalendar.getApi()
this.year = this.today.year
this.month = this.today.month
this.calendarOptions.events = this.calendarEvents
this.setDate(this.addDate(this.currentFirstDate,-1))
},
watch: {
calendarEvents:{
handler: function(val, oldVal) {
this.calendarOptions.events = val
},
deep: true
},
myCalendar:{
handler: function(val, oldVal) {
this.ismyCalendar = val
},
deep: true
},
taskSval:{
handler: function(val, oldVal) {
this.taskSchedule = val
},
deep: true
},
},
computed:{
titlehearsd:function(){
if(this.calendarOptions.initialView == 'dayGridMonth'){
return this.year+'年'+this.month+'月'
}else{
return this.timeStamp[0]+'—'+this.timeStamp[6]
}
},
},
methods: {
/**
* 自定义头部事件
*/
changeViewTypeFn(val){
this.calendarApi.changeView(val)
this.calendarOptions.initialView = val
this.todayFn()
},
getDates(date) {
var year = date.getFullYear()
var month = ((date.getMonth() + 1)).length === 2 ? ('0' + (date.getMonth() + 1) ) : (date.getMonth() + 1)
var day = (date.getDate() + '').length === 1 ? ('0' + date.getDate()) : date.getDate()
this.timeStamp.push(year +'年'+ month +'月'+day+'日')
return year + month + day
},
addDate(date, n) {
date.setDate(date.getDate() + n)
return date
},
setDate(date) {
this.timeStamp = []
var week = date.getDay() - 1
date = this.addDate(date, week * -1)
this.currentFirstDate = new Date(date)
for (var i = 0; i < 7; i++) {
this.getDates(i === 0 ? date : this.addDate(date, 1)) // 星期一开始
}
},
prevFn(){
if(this.calendarOptions.initialView == 'dayGridMonth'){
if(this.month == 1){
this.month = 12
this.year--
this.calendarApi.prev()
this.disabledtoday = false
}else{
this.month--
this.calendarApi.prev()
this.disabledtoday = false
}
}
if(this.calendarOptions.initialView == 'timeGridWeek'){
this.calendarApi.prev()
this.setDate(this.addDate(this.currentFirstDate, -7))
this.disabledtoday = false
}
},
nextFn(){
if(this.calendarOptions.initialView == 'dayGridMonth'){
if(this.month == 12){
this.month = 1
this.year++
this.calendarApi.next()
this.disabledtoday = false
}else{
this.month++
this.calendarApi.next()
this.disabledtoday = false
}
}
if(this.calendarOptions.initialView == 'timeGridWeek'){
this.setDate(this.addDate(this.currentFirstDate, 7))
this.calendarApi.next()
this.disabledtoday = false
}
},
todayFn () {
this.calendarApi.today()
this.disabledtoday = true
if(this.calendarOptions.initialView == 'dayGridMonth'){
this.today = calendar.getNewDate(new Date())
this.year = this.today.year
this.month = this.today.month
}else{
this.currentFirstDate = new Date()
this.setDate(this.addDate(this.currentFirstDate,-1))
}
},
//点击日期
handleDateClick: function(info) {
console.log( this.$refs.fullCalendar.style)
if(this.ismyCalendar == true){
this.$emit('handleDateClick', info)
}else{
return
}
},
//点击事件
eventClick: function(info) {
this.$emit('eventClick', info)
},
//选择日程或者任务
changeTask(val){
this.$emit('changeTask', val)
},
},
beforeDestroy () {
// this.calendar = null
// this.instance = null
this.calendarApi.render()
},
destroyed() {
this.calendarApi.destroy()
}
}
</script>
<style scoped>
.fc table>thead>tr>th div {
font-weight: bold;
color: #25992E;
font-size: 16px;
}
.fc-sat span, .fc-sun div {
color: #ED6D23 !important;
}
.fc-ltr .fc-basic-view .fc-day-top .fc-day-number {
width: 100%;
text-align: right;
display: block;
font-size: 20px;
font-family: Arial;
font-weight: 600;
padding: 12px 12px 0 12px;
line-height: 23px;
height: 23px;
color: #555;
}
.fc-day-cnTerm {
text-align: right;
padding: 12px 12px 0 12px;
color: #6ABA49;
font-size: 12px;
}
.fc-day-cnDate {
text-align: right;
padding: 12px 12px 0 12px;
color: #999;
font-size: 12px;
}
</style>
组件使用
firstday:设置一周中显示的第一天是哪天,周日是0,周一是1
taskSval:日程还是任务【你们不需要可以删除,】
calendarEvents, //日历显示时间数据
myCalendar:是不是自己日程【你们不需要可以删除,】
<Calendar
ref="Calendars"
:firstday="firstday"
:myCalendar="myCalendar"
:calendarEvents="programmevents"
:taskSval="taskSval"
@handleDateClick="DateClick"
@eventClick="eventClick"
@changeTask="changeTask"
></Calendar>
日程添加重复任务
安装fullcalendar中第三方插件rrulePlugin,npm install --save @fullcalendar/rrule
在上一步代码已经导入,import rrulePlugin from '@fullcalendar/rrule'
> 我这边后台给数据不合符fullcalendar中数据格式,我转一下,你们可以根据自己需求的
//转化数据
getenev(date){
let starts = ''
let ends = ''
let newdata = []
let color= ''//状态颜色
let endNewDate =''
for (let i = 0; i < date.length; i++) {
//优先级,0-低,1-普通,2-紧急,3-非常紧急
if(date[i].priorityLevel){
switch (date[i].priorityLevel){
case 0:
color ="rgb(245,147,8, 0.2)"
break;
case 1:
color ="rgb(0,255,0, 0.2)"
break;
case 2:
color ="rgb(1,190,216, 0.2)"
break;
case 3:
color =" rgb(248,82,67, 0.2)"
break;
}
}
newdata.push({
id:date[i].id,
title:date[i].title,
start:date[i].startDate+' '+date[i].startTime,
end: date[i].endDate+' '+date[i].endTime,
// startRecur: '2021-01-1T10:00:00',
// endRecur: '2021-01-17T16:00:00',
extendedProps: {
describes: date[i].describes,
place:date[i].place,
startDate:date[i].startDate,
endDate:date[i].endDate,
startTime:date[i].startTime,
endTime:date[i].endTime,
title:date[i].title,
id:date[i].id,
// jobId:date[i].jobId,
repeatTime:date[i].repeatTime,//重复时间,0-不重复,1-每天重复,2每周重复,3-每月重复,4-每年重复,5-工作日重复
reminderTime:date[i].reminderTime,//提醒时间 0不提醒,1五分钟,2十五分钟,3三十分钟,4一个小时,5一天前,6一个月前
remindMode:date[i].remindMode,//提醒方式 0应用提醒,1短信提醒,2电话提醒
priorityLevel:date[i].priorityLevel,//优先级,0-低,1-普通,2-紧急,3-非常紧急
taskSchedule:date[i].taskSchedule,//任务或者日程,0任务,1日程
privacyPatter:date[i].privacyPatter,//隐私模式,0公开模式,1隐私模式
calendarNotifyDtoList:date[i].calendarNotifyDtoList,//renyuan
},
borderColor:color,
color: color,
textColor: 'black' ,
//displayEventEnd:false ,
// allDay : true,
})
let _this =this
newdata.forEach( function(item){
//每天重复
if(item.extendedProps.repeatTime == 1){
let rrule ={}
_this.$set(item, 'rrule',{
freq: "daily",
dtstart: item.start,
until: item.end,
interval:1
})
}
//2每周重复
if(item.extendedProps.repeatTime == 2){
let rrule ={}
_this.$set(item, 'rrule',{
freq: "weekly",
dtstart: item.start,
//byweekday: ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'su' ],
until: item.end,
//interval:1
})
}
//3-每月重复
if(item.extendedProps.repeatTime == 3){
let rrule ={}
_this.$set(item, 'rrule',{
freq: "monthly",
dtstart: item.start,
until: item.end,
interval:1
})
}
//4-每年重复
if(item.extendedProps.repeatTime == 4){
let rrule ={}
_this.$set(item, 'rrule',{
freq: "yearly",
dtstart: item.start,
until: item.end,
interval:1
})
}
})
}
return newdata
},
日程添加农历显示
calendarnongli.js是农历计算js
https://download.csdn.net/download/lny1126/15117097
总结
我这边主要是根据我需求改,你们可以根据自己需求,不用代码可以删除,