vue fullCalendar的使用及扩展(支持农历显示及鼠标右键新建)

    技术2022-07-13  76

    引入步骤

    1、安装插件

    yarn add @fullcalendar/vue @fullcalendar/core @fullcalendar/daygrid @fullcalendar/interaction @fullcalendar/list @fullcalendar/timegrid

    2、引入组件

    html代码

    <template> <div> <FullCalendar ref="myCalendar" :options="calendarOptions"/> </div> </template>

    js代码

    import FullCalendar from '@fullcalendar/vue' import dayGridPlugin from '@fullcalendar/daygrid' import timeGridPlugin from '@fullcalendar/timegrid' import interactionPlugin from '@fullcalendar/interaction' import listPlugin from '@fullcalendar/list' export default { components: { FullCalendar // make the <FullCalendar> tag available }, data() { return { calendarOptions: { plugins: [ dayGridPlugin,interactionPlugin,timeGridPlugin,listPlugin ], initialView: 'timeGridWeek', events: [ { title: 'event 1', date: '2020-06-01',classNames:['cal'] }, { title: 'event 2', date: '2020-06-02',classNames:['inv'] }, { title: '公司会议', start: '2020-06-22 09:05', end:'2020-06-23 12:00',classNames:['cal'] }, { title: '部门会议', start: new Date(),classNames:['cal'] }, ], headerToolbar: { left: 'title prev,next', center: '', right: 'today dayGridMonth,timeGridWeek,listDay' }, buttonText:{ today:'今天', month:'月视图', week:'周视图', day:'日视图', list:'列表视图', }, displayEventEnd: true, //所有视图显示结束时间 dateClick:this.handleDateClick, allowContextMenu:false, editable: true, selectable: true, selectMirror: true, dayMaxEvents: true, weekends: true, } } }

    css样式   scss

    .fc-daygrid-event{ .fc-daygrid-event-dot{ display:none; } &.cal{ padding-left:5px; color:#333; border-radius: 0; border:none; border-left: 2px solid #5289FF; background-color:#EEF3FF; .fc-event-title{ color:#333; } } &.inv{ padding-left:5px; color:#333; border-radius: 0; border:none; border-left: 2px solid #FFA327; background-color:#FFF6E9; .fc-event-title{ color:#333; } } } .fc-timegrid-event{ .fc-daygrid-event-dot{ display:none; } &.cal{ padding-left:5px; color:#333; border-radius: 0; border:none; border-left: 2px solid #5289FF; background-color:#EEF3FF; .fc-event-title{ color:#333; } } &.inv{ padding-left:5px; color:#333; border-radius: 0; border:none; border-left: 2px solid #FFA327; background-color:#FFF6E9; .fc-event-title{ color:#333; } } } .fc .fc-toolbar-title{ display: inline-block; vertical-align: middle; } .fc-theme-standard td{ border-top-color:transparent; }

    效果图:

    -------------------------------------------------------------------------------------------------------------

    扩展--------------------------------------------

    1、月视图增加农历

    calendarOptions中增加views数据;

    通过dayCellContent来设置日期里显示的数据;

    引入calendar.js计算农历 https://github.com/jjonline/calendar.js;

    import calenderFormate from "../utils/calendar" //农历计算方法 import {formatDate} from "../utils/index" //将日期对象转换成 2020-01-01 格式的日期 //data中calendarOptions修改: calendarOptions: { views:{ //对应月视图 dayGridMonth:{ displayEventTime:false,//是否显示时间 dayCellContent(item){ let _date=formatDate(item.date).split('-') let _dateF=calenderFormate.solar2lunar(_date[0],_date[1],_date[2]) return {html:`<p><label>${_dateF.cDay}</label><span>${_dateF.IDayCn}</span></p>`} }, } }, }

    效果如下图:

     

    2、周视图增加农历

    在前面的基础上修改views;

    在dayHeaderContent中设置显示数据;

    views: { //对应周视图调整 timeGridWeek:{ slotMinTime:"09:00",//周视图开始时间 slotMaxTime:"20:00",//周视图结束时间 displayEventTime:false,//是否显示时间 dayHeaderContent(item){ let _date=formatDate(item.date).split('-') let _dateF=calenderFormate.solar2lunar(_date[0],_date[1],_date[2]) return {html:`<h3>${_dateF.ncWeek.slice(2)}</h3><p><label>${_dateF.cDay}</label><span>${_dateF.IDayCn}</span></p>`} } } }

    效果图如下

    *注 周视图中配置了dayHeaderContent后,如果还有日视图,但是日视图没有特殊配置会出现一个bug:从周视图切到日视图,日视图的header会变成undefined,而不是正常的“星期...”

    解决方法:在日视图的配置中也给出 dayHeaderContent的配置即可(具体原因没有深入探索)。

    timeGridDay:{ dayHeaderContent(item){ return {html:`<h3>${item.text}</h3>`} } }

    非常感谢网友 weixin_40712964 反馈这个bug!

    3、修改周视图时间点显示格式为24小时制

    calendarOptions中增加设置属性slotLabelFormat

    slotLabelFormat:{ hour: '2-digit', minute: '2-digit', meridiem: false, hour12: false //设置时间为24小时 },

     效果图如下所示:

    4、calendarOptions中其他设置

    calendarOptions:{ select: this.handleDateSelect,//选择日期事件,可响应一个新建日程的事件 eventClick: this.handleEventClick,//点击事件对象事件 schedulerLicenseKey: 'CC-Attribution-NonCommercial-NoDerivatives'//试用证书 } //methods中定义相应的事件 handleDateSelect(selectInfo) { let title = prompt('Please enter a new title for your event') let calendarApi = selectInfo.view.calendar calendarApi.unselect() // clear date selection if (title) { calendarApi.addEvent({ id: createEventId(), title, start: selectInfo.startStr, end: selectInfo.endStr, allDay: selectInfo.allDay, classNames:['cal'] }) } }, handleEventClick(clickInfo) { if (confirm(`Are you sure you want to delete the event '${clickInfo.event.title}'`)) { clickInfo.event.remove() } },

    效果:

    -----------------------------------------------------------------------------------------------------------

    ****修改源码,实现右键选择日期新建效果

    修改node_modules\@fullcalendar\interaction文件夹中的main.js

    在方法PointerDragging中增加代码

    containerEl.addEventListener('contextmenu', (e)=>{ e.preventDefault() this.handleMouseUp });

     

    修改isPrimaryMouseButton方法的判断逻辑

    function isPrimaryMouseButton(ev) { return (ev.button === 0||ev.button ===2) && !ev.ctrlKey; }

     此时,鼠标右键的效果和鼠标左键效果一致,可以点击日期新建,也可以拖选日期新建。

    -----------------------------------------------------------------------------------------------------------

    ****修改源码,解决IE9中报Intl未定义错误

    1、下载Intl.js文件

    地址:https://github.com/andyearnshaw/Intl.js/

    将Intl.js-master\dist\Intl.complete.js文件放入public文件夹中

    2、index.html中引入改文件

    <head> <script src="<%= BASE_URL %>Intl.complete.js"></script> </head>

    3、修改 node_modules\@fullcalendar\common\main.js文件。将Intl替换成IntlPolyfill并保存文件

    -----------------------------------------------------------------------------------------------------------

    ****解决IE9中不支持classList

    在 index.html文件前面增加如下代码

    if (!("classList" in document.documentElement)) { Object.defineProperty(HTMLElement.prototype, 'classList', { get: function() { var self = this; function update(fn) { return function(value) { var classes = self.className.split(/\s+/g), index = classes.indexOf(value); fn(classes, index, value); self.className = classes.join(" "); } } return { add: update(function(classes, index, value) { if (!~index) classes.push(value); }), remove: update(function(classes, index) { if (~index) classes.splice(index, 1); }), toggle: update(function(classes, index, value) { if (~index) classes.splice(index, 1); else classes.push(value); }), contains: function(value) { return !!~self.className.split(/\s+/g).indexOf(value); }, item: function(i) { return self.className.split(/\s+/g)[i] || null; } }; } }); }

     此时,fullCalendar基本上可以在IE9上面运行。只不过IE9中不支持flex布局,可能会布局有点错乱。

     

    Processed: 0.019, SQL: 9