fullcalendar v5封装一个日程组件

最近在客户端的日程中用到的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

总结

我这边主要是根据我需求改,你们可以根据自己需求,不用代码可以删除,


在这里插入图片描述
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,978评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,954评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,623评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,324评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,390评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,741评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,892评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,655评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,104评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,569评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,254评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,834评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,725评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,950评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,260评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,446评论 2 348

推荐阅读更多精彩内容