效果图:

官方文档地址:Vue Component - Docs | FullCalendar

1、安装与FullCalendar相关的依赖项

npm install --save @fullcalendar/vue @fullcalendar/daygrid

2、在模板中添加标签

<full-calendar ref="fullCalendar" style="height: 100%" :options="calendarOptions"></full-calendar>

3、在页面中引入需要的组件

// 引入日历组件
import FullCalendar from "@fullcalendar/vue";
import dayGridPlugin from "@fullcalendar/daygrid";
import interactionPlugin from "@fullcalendar/interaction";

4、在data中设置日历的一些配置及属性

data(){
  return{
      calendarOptions: {
        //   timeGridPlugin  可显示每日时间段
        height: 700,
        plugins: [dayGridPlugin, interactionPlugin],
        headerToolbar: {
          left: "prev,next today",
          center: "title",
          right: "dayGridMonth,dayGridWeek,dayGrid",
          // right: 'agendaWeek,dayGridWeek,dayGrid'
        },
        buttonText: {
          // 设置按钮
          today: "今天",
          month: "月",
          week: "周",
          dayGrid: "天",
        },
        // allDaySlot: false,
        editable: true,
        selectable: true,
        navLinks: true,
        // displayEventEnd: true,//所有视图显示结束时间
        initialView: "dayGridMonth", // 设置默认显示月,可选周、日
        dateClick: this.handleDateClick,
        eventClick: this.handleEventClick,
        eventsSet: this.handleEvents,
        select: this.handleDateSelect,
        // timezone
        // 设置日程
        events: [
          // {
          // 	id: 1,
          // 	title: '09:30~11:30 小破孩',
          // 	start: '2020-12-11',
          // 	end: '2020-12-13',
          // 	color: '#f08f00',
          // },
          // {
          // 	id: 2,
          // 	title: '9:30~14:30 项目会议',
          // 	start: '2020-12-14',
          // 	end: '2020-12-14',
          // 	color: '#6bb377',
          // },
        ],
        eventColor: "#f08f00", // 修改日程背景色
        locale: "zh-cn", // 设置语言
        weekNumberCalculation: "ISO", // 周数
        customButtons: {
          prev: { // this overrides the prev button
            text: "PREV",
            click: () => {
              this.prev();
            }
          },
          next: { // this overrides the next button
            text: "PREV",
            click: () => {
              this.next();
            }
          },
          today: {
            text: "今天",
            click: () => {
              this.today();
            }
          }
        }
      },
  }
}

5、在mounted中添加获取日历信息方法

mounted() {
    // 获取用户信息
    this.calendarApi = this.$refs.fullCalendar.getApi();
},

6、在methods中添加点击上一月、下一月和今天的事件

methods:{
    prev() {
      this.calendarApi.prev();
    },
    // 切换下一个按钮事件
    next() {
      this.calendarApi.next();
    },
    // 点击今天按钮
    today() {
      this.calendarApi.today();
    },
}

7、在methods中添加点击某一天区域的事件

methods:{
    handleDateClick: function (arg) {
      this.$forceUpdate();
      console.log(arg,'事件1')
    },
}

8、在methods中添加点击某一日程的事件

methods:{
    handleEventClick(calEvent) {
      console.log(calEvent,'事件2');
      this.dialogVisible = true; // 显示dialog弹窗
      let id = calEvent.event.id; // 获取当前点击日程的ID
      let info = this.subList.filter((item) => {
        return item.id == id // 通过ID进行数据匹配 
      });
      this.$nextTick(() => {
        this.form = _.cloneDeep(info[0]); // 数据通过深拷贝赋值到form表单用于编辑
        this.getShowTime(this.form.beginDate, this.form.endDate); // 处理时间回显格式
        console.log(info[0],'数据')
      });
    },
}

处理时间格式的方法:

methods:{
    getShowTime(beginDate, endDate) {
      this.form.startDate = this.dealWithTime(beginDate);
      this.form.startTime = this.getHoursMin(beginDate);
      this.form.endDate = this.dealWithTime(endDate);
      this.form.endTime = this.getHoursMin(endDate);
    },
    // 获取时分时间
    getHoursMin(value) {
      return value.substring(11, 16);
    },
    // 处理会议时间格式
    dealWithTime(date) {
      let newDate = /\d{4}-\d{1,2}-\d{1,2}/g.exec(date)[0];
      return newDate;
    },
}

第8步中 “处理时间回显格式” 解析:

因为后台返回的是一个整体的年月日时分秒格式,所以需要拆分为年月日和时分秒分别显示

9、在methods中添加点击某一天日期数字,切换至显示当前所有日程的事件

methods:{
    handleEvents(events) {
      console.log(events,'事件3');
    },
}

10、数据赋值然后渲染至日历上

数据格式:

// 会议室1日程安排
let scheduleList0 = [
    {id: 1, title: '小破孩', userId: 3, beginDate: '2020-12-11 09:30', endDate: '2020-12-13 11:30', remark: '备注内容', status: '#f08f00'},
    {id: 2, title: '项目会议', userId: 2, beginDate: '2020-12-14 09:30', endDate: '2020-12-14 14:30', remark: '备注内容', status: '#6bb377'},
    {id: 3, title: '供应商接待', userId: 3, beginDate: '2020-12-18 10:00', endDate: '2020-12-18 12:30', remark: '备注内容', status: '#6bb377'},
    {id: 4, title: '部门周会', userId: 2, beginDate: '2020-12-18 13:30', endDate: '2020-12-19 15:30', remark: '备注内容', status: '#999'},
    {id: 5, title: '项目分析会', userId: 1, beginDate: '2020-12-29 14:30', endDate: '2020-12-29 17:00', remark: '备注内容', status: '#6bb377'},
];

赋值方法:

methods:{
    getReservationList(arrayData){
      let newArr = [];
      this.subList = arrayData;
      arrayData.forEach((item) => {
        newArr.push({
          start: this.dealWithTime(item.beginDate),
          end: this.addDate(this.dealWithTime(item.endDate), 1),
          color: item.status,
          id: item.id,
          title: `${this.getTitle(item.beginDate, item.endDate)} ${item.title}`,
        })
      });
      this.calendarOptions.events = newArr;
    },
}

日期分割和title处理:

methods:{
    // 日期加1天
    addDate(date, days) {
      var d = new Date(date);
      d.setDate(d.getDate() + days);
      var mon = (d.getMonth() + 1) < 10 ? "0" + (d.getMonth() + 1) : d.getMonth() + 1;
      let endD = d.getDate() < 10 ? '0' + d.getDate() : d.getDate();
      return `${d.getFullYear()}-${mon}-${endD}`;
    },
    // 获取会议事件title
    getTitle(date1, date2) {
      let start = date1.substring(11, 16);
      let end = date2.substring(11, 16);
      return `${start}~${end}`;
    },
}

附加data中更多配置项,如下:

theme:false,//如果设置为true,则需要加载jquery ui相关css和js文件,默认值为false
firstDay:1,//设置一周中显示的第一天是哪天,周日是0,周一是1,类推
isRTL:false,//设置为ture时则日历从右往左显示
weekends:true,//是否显示周末,设为false则不显示周六和周日。默认值为true
hiddenDays:[],//隐藏一周中的某一天或某几天,数组形式,如隐藏周二和周五:[2,5],默认不隐藏,除非weekends设置为false。
weekMode:'fixed',//在月视图里显示周的模式,因为每月周数可能不同,所以月视图高度不一定。fixed:固定显示6周高,日历高度保持不变liquid:不固定周数,高度随周数变化variable:不固定周数,但高度固定
weekNumbers:false,//是否在日历中显示周次(一年中的第几周),如果设置为true,则会在月视图的左侧、周视图和日视图的左上角显示周数。
weekNumberCalculation:'iso',//周次的显示格式。
//height:600,//设置日历的高度,包括header日历头部,默认未设置,高度根据aspectRatio值自适应。
//contentHeight://设置日历主体内容的高度,不包括header部分,默认未设置,高度根据aspectRatio值自适应。
aspectRatio:1.35,//设置日历单元格宽度与高度的比例。
handleWindowResize:true,//是否随浏览器窗口大小变化而自动变化。
render:function(view){
     console.log('render',view)
},//method,绑定日历到id上。$('#id').fullCalendar('render');
destroy:function(){
                            
},
weekNumbers : false,     //是否在视图左边显示这是第多少周,默认false
                
eventLimit: true,       //数据条数太多时,限制各自里显示的数据条数(多余的以“+2more”格式显示),默认false不限制,支持输入数字设定固定的显示条数
         
viewRender : function(view,element){//在视图被渲染时触发(切换视图也触发) 参数view为视图对象,参数element为Jquery的视图Dom
                                
                        },
          
dayRender : function(date, cell){//日期格式Render钩子函数(我没理解清楚)
      console.log("↓↓↓dayRender↓↓↓");
      console.log(date);
      console.log(cell);
},
windowResize : function(){//浏览器窗体变化时触发
      console.log("---windowResize---");
},
        
allDayText : "全天",            //自定义全天视图的名称
slotDuration : "01:00:00",      //一格时间槽代表多长时间,默认00:30:00(30分钟)
slotLabelFormat : "H(:mm)a",    //日期视图左边那一列显示的每一格日期时间格式
slotLabelInterval : "02:00:00", //日期视图左边那一列多长间隔显示一条日期文字(默认跟着slotDuration走的,可自定义)
snapDuration : "05:00:00",      //其实就是动态创建一个日程时,默认创建多长的时间块
          
slotEventOverlap : false,       //相同时间段的多个日程视觉上是否允许重叠,默认true允许
        
noEventsMessage : "L没数据啊",   //listview视图下,无数据时显示提示
defaultDate  : '2018-09-10',    //默认显示那一天的日期视图getDates(true)
nowIndicator : true,            //周/日视图中显示今天当前时间点(以红线标记),默认false不显示
monthNames : ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], //月份自定义命名
monthNamesShort: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], //月份缩略命名(英语比较实用:全称January可设置缩略为Jan)
dayNames: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"],       //同理monthNames
dayNamesShort: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"],  //同理monthNamesShort
weekNumberTitle : "周",         //周的国际化,默认为"W"
        
eventLimitText  : "更多",       //当一块区域内容太多以"+2 more"格式显示时,这个more的名称自定义(应该与eventLimit: true一并用)
                        dayPopoverFormat : "YYYY年M月d日", //点开"+2 more"弹出的小窗口标题,与eventLimitClick可以结合用
                        navLinks : true,                // “xx周”是否可以被点击,默认false,如果为true则周视图“周几”被点击之后进入日视图。本地测试:没什么效果
                          
dayClick: function(date, jsEvent, view) {//空白的日期区,单击时触发
       console.log("↓↓↓dayClick↓↓↓");
       console.log('Clicked on: ' + date.format());
       console.log('Coordinates: ' + jsEvent.pageX + ',' + jsEvent.pageY);
       console.log('Current view: ' + view.name);                 
       //$(this).css('background-color', 'red');
},
eventClick: function(calEvent, jsEvent, view) {//日程区块,单击时触发
       console.log(jsEvent.target)
       alert(jsEvent.target.innerHTML)
       console.log("↓↓↓eventClick↓↓↓");
       console.log('Event: ' + calEvent.title);
       console.log('Coordinates: ' + jsEvent.pageX + ',' + jsEvent.pageY);
       console.log('Current view: ' + view.name);
       return false;  //return false可以阻止点击后续事件发生(比如event中的url跳转事件)
},
eventMouseover: function(calEvent, jsEvent, view){//鼠标在日程区块上时触发
       console.log(jsEvent)
       console.log(calEvent.start._i)
       $('.hover-dateStr').html(calEvent.start._i)
       console.log(jsEvent.pageY,jsEvent.pageX)
       $('.hover-container').removeClass('none').animate({'top':jsEvent.pageY,'left':jsEvent.pageX})
       if(!canRun){
             // 判断是否已空闲,如果在执行中,则直接return
             return;
         }
},
eventMouseout: function(calEvent, jsEvent, view){//鼠标从日程区块离开时触发
                            $('.hover-container').addClass('none')
                        },
                        selectable: false,           //允许用户可以长按鼠标选择多个区域(比如月视图,可以选中多天;日视图可以选中多个小时),默认false不能选择多区域的
                        selectHelper: true,         //接selectable,周/日视图在选择时是否预先画出“日程区块”的样式出来
                        unselectAuto : true,        //是否点击页面上的其他地方会导致当前的选择被清除,默认true
                        unselectCancel : "",        //一种方法来指定元素,会忽略unselectauto选项,默认''
                        selectOverlap : true,       //确定用户是否被允许选择被事件占用的时间段,默认true可占用时间段
                        
                        selectAllow : function(selectInfo){ //精确的编程控制用户可以选择的地方,返回true则表示可选择,false表示不可选择
                            console.log("↓↓↓selectConstraint↓↓↓");
                            console.log("start:"+selectInfo.start+"|end:"+selectInfo.end+"|resourceId:"+selectInfo.resourceId);
                            return true;
                        },
                        select: function(start, end,jsEvent,view) { //点击空白区域/选择区域内容触发
        
                        },
                        unselect : function(view, jsEvent){//选择操作取消时触发
                            console.log("↓↓↓unselect↓↓↓");
                            console.log("view:"+view);
                        },
                          
                        lazyFetching : true,        //是否启用懒加载技术--即只取当前条件下的视图数据,其它数据在切换时触发,默认true只取当前视图的,false是取全视图的
                        defaultTimedEventDuration : "02:00:00",     //在Event Object中如果没有end参数时使用,如start=7:00pm,则该日程对象时间范围就是7:00~9:00
                        defaultAllDayEventDuration : { days: 1 },  //默认1天是多长,(有的是采用工作时间模式,所以支持自定义)
                        loading : function(isLoading, view){ //视图数据加载中、加载完成触发
                                console.log("↓↓↓loading↓↓↓");
                                if(isLoading == true){
                                    console.log("view:"+view+",开始加载");
                                }else if(isLoading == false){
                                    console.log("view:"+view+",加载完成");
                                }else{
                                    console.log("view:"+view+",除非天塌下来否则不会进这个分支");
                                }
                            },
              
                            eventOrder : "title",           //多个相同的日程数据排序方式,String / Array / Function, 默认值: "title"
                            eventRender : function(event, element, view) {          //当Event对象开始渲染时触发
                                console.log("eventRender():"+event.title);
                            },
                            eventAfterAllRender : function(view){console.log("eventAfterAllRender();");},   //当所有Event对象渲染完成时触发
                            editable: true,                 //支持Event日程拖动修改,默认false
                            eventStartEditable : true,      //Event日程开始时间可以改变,默认true,如果是false其实就是指日程块不能随意拖动,只能上下拉伸改变他的endTime
                            eventDurationEditable : false,  //Event日程的开始结束时间距离是否可以改变,默认true,如果是false则表示开始结束时间范围不能拉伸,只能拖拽
             
                            dragOpacity:0.2,                //拖拽时不透明度,0.0~1.0之间,数字越小越透明
                            dragScroll : true,              //是否在拖拽时自动移动容器,默认true
                            eventOverlap : true,            //拖拽时是否重叠
                            eventConstraint : {     //限制拖拽拖放的位置(即限制有些地方拖不进去):an event ID, "businessHours", object
                                start: '10:00',     // a start time (10am in this example)
                                end: '18:00',       // an end time (6pm in this example)
                                dow: [ 1, 2, 3, 4 ] // days of week. an array of zero-based day of week integers (0=Sunday)  (Monday-Thursday in this example)
                            },
                            longPressDelay : 1000,  //面向可touch设备(如移动设备),长按多少毫秒即可拖动,默认1000毫秒(1S)
                            eventDragStart : function(event, jsEvent, ui, view){    //日程开始拖拽时触发
                                console.log("eventDragStart():"+event.title);
                            },
                            eventDragStop : function(event, jsEvent, ui, view){     //日程拖拽停止时触发
                                console.log("eventDragStop():"+event.title);
                            },
                            eventDrop : function(event, delta, revertFunc, jsEvent, ui, view){  //日程拖拽停止并且已经拖拽到其它位置了
                                console.log("eventDrop():"+event.title);
                            },
                            eventResizeStart : function( event, jsEvent, ui, view ) {       //日程大小调整开始时触发
                                console.log("eventResizeStart():"+event.title);
                            },
                            eventResizeStop : function(event, jsEvent, ui, view){           //日程大小调整停止时触发
                                console.log("eventResizeStop():"+event.title);
                            },
                            eventResize : function(event, delta, revertFunc, jsEvent, ui, view){    //日程大小调整完成并已经执行更新时触发
                                console.log("eventResize():"+event.title);
                            },
                            events:[
                                        {
                                            "time": "9:20--18:20",
                                            "antualTime":"9:40--18:40",
                                            "start": "2018-09-01"
                                            
                                        },
                                        {
                                            "time": "9:40--18:40",
                                            "antualTime":"9:40--18:40",
                                            "start": "2018-09-02"
                                        }
                                    ]

最近很多小伙伴留言说需要完整版代码,然后就抽空整理了一下,已经上传了,

更多API配置参考:FullCalendar日历插件(中文API) - zrSoldier - 博客园

有需要的小伙伴可以自主下载:vue+Fullcalendar.zip_vuefullcalendar添加日程-互联网文档类资源-CSDN下载

至此完成

尊重原创,感谢支持

Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐