fullCalendar日歷插件玩法示例解析
fullCalendar日歷插件玩法解析
fullCalendar日歷
1、在用之前我先介紹為啥要用這個(gè)fullcalendar日歷插件,首先我在用之前是用的Ant Design of Vue框架的日歷,這個(gè)框架的日歷就比較單調(diào)沒有很靈活的能操作日歷里面的日歷日程,而fullcalendar日歷就能很靈活的進(jìn)行日歷方面的操作。
2、在剛開始用的時(shí)候還是有太多坑的,fullCalendar日歷插件在我現(xiàn)在發(fā)現(xiàn)的有(vue-full-calendar 、vue-fullcalendar 、 calendar),凡是看到npminstall以上三個(gè)的就不要去下載了,雖然vue-fullcalendar是可以使用的,但想要使用下載fullCalendar里面的其它包是不可以的。
Fullcalendar安裝
安裝所需要的npm包
npm install --save @fullcalendar/vue 下面包是日歷的周視圖、日視圖等插件包: npm install --save @fullcalendar/core @fullcalendar/daygrid @fullcalendar/interaction @fullcalendar/list @fullcalendar/timegrid 安裝后的fullcalendar源碼和其它插件都會在@fullcalendar
導(dǎo)入HTML
<template> <div> <FullCalendar ref="myCalendar" :options="calendarOptions"/> </div> </template>
導(dǎo)入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 { name: 'MaintenanceCalendarview', components: { FullCalendar }, data () { return { calendarOptions: { // 引入的插件,比如fullcalendar/daygrid,fullcalendar/timegrid引入后才可顯示月,周,日 plugins: [ dayGridPlugin, interactionPlugin, timeGridPlugin, listPlugin ], initialView: 'dayGridMonth', // 默認(rèn)為那個(gè)視圖(月:dayGridMonth,周:timeGridWeek,日:timeGridDay) firstDay: 1, // 設(shè)置一周中顯示的第一天是哪天,周日是0,周一是1,類推 locale: 'zh-cn', // 切換語言,當(dāng)前為中文 eventColor: '#3BB2E3', // 全部日歷日程背景色 themeSystem: 'bootstrap', // 主題色(本地測試未能生效) initialDate: moment().format('YYYY-MM-DD'), // 自定義設(shè)置背景顏色時(shí)一定要初始化日期時(shí)間 timeGridEventMinHeight: '20', // 設(shè)置事件的最小高度 aspectRatio: 1.65, // 設(shè)置日歷單元格寬度與高度的比例。 // displayEventTime: false, // 是否顯示時(shí)間 // allDaySlot: false, // 周,日視圖時(shí),all-day 不顯示 eventLimit: true, // 設(shè)置月日程,與all-day slot的最大顯示數(shù)量,超過的通過彈窗顯示 headerToolbar: { // 日歷頭部按鈕位置 left: '', center: 'prevYear,prev title next,nextYear', right: 'today dayGridMonth,timeGridWeek,timeGridDay' }, buttonText: { today: '今天', month: '月', week: '周', day: '日' }, slotLabelFormat: { hour: '2-digit', minute: '2-digit', meridiem: false, hour12: false // 設(shè)置時(shí)間為24小時(shí) }, eventLimitNum: { // 事件顯示數(shù)量限制(本地測試未能生效) dayGrid: { eventLimit: 5 }, timeGrid: { eventLimit: 2 // adjust to 6 only for timeGridWeek/timeGridDay } }, // 事件 // eventClick: this.handleEventClick, // 點(diǎn)擊日歷日程事件 eventDblClick: this.handleEventDblClick, // 雙擊日歷日程事件 (這部分是在源碼中添加的) eventClickDelete: this.eventClickDelete, // 點(diǎn)擊刪除標(biāo)簽事件 (這部分是在源碼中添加的) eventDrop: this.eventDrop, // 拖動日歷日程事件 eventResize: this.eventResize, // 修改日歷日程大小事件 select: this.handleDateSelect, // 選中日歷格事件 eventDidMount: this.eventDidMount, // 安裝提示事件 // loading: this.loadingEvent, // 視圖數(shù)據(jù)加載中、加載完成觸發(fā)(用于配合顯示/隱藏加載指示器。) // selectAllow: this.selectAllow, //編程控制用戶可以選擇的地方,返回true則表示可選擇,false表示不可選擇 eventMouseEnter: this.eventMouseEnter, // 鼠標(biāo)滑過 allowContextMenu: false, editable: true, // 是否可以進(jìn)行(拖動、縮放)修改 eventStartEditable: true, // Event日程開始時(shí)間可以改變,默認(rèn)true,如果是false其實(shí)就是指日程塊不能隨意拖動,只能上下拉伸改變他的endTime eventDurationEditable: true, // Event日程的開始結(jié)束時(shí)間距離是否可以改變,默認(rèn)true,如果是false則表示開始結(jié)束時(shí)間范圍不能拉伸,只能拖拽 selectable: true, // 是否可以選中日歷格 selectMirror: true, selectMinDistance: 0, // 選中日歷格的最小距離 dayMaxEvents: true, weekends: true, navLinks: true, // 天鏈接 selectHelper: false, slotEventOverlap: false // 相同時(shí)間段的多個(gè)日程視覺上是否允許重疊,默認(rèn)true允許 } } }, methods: { eventMouseEnter (event, jsEvent, view) { // 鼠標(biāo)劃過的事件 if (event.event.classNames.length) { // console.log(event) } }, eventDrop (event, dayDelta, minuteDelta, allDay, revertFunc, jsEvent, ui, view) { console.log(event) } } }
(以上日歷事件以及event事件差不多這些都是我個(gè)人感覺能用到的我才加進(jìn)去了)
event: [ ] ==>(event能否進(jìn)行操作真正取決于開始日期和結(jié)束日期的格式,即使是設(shè)置了editable,時(shí)間還是會影響 ,一共有四種情況,當(dāng)日期時(shí)間為00:00到23:59時(shí)為全天)
events: [ { title : '可以拖動但不能縮放', start : '2019-07-01 12:30', end : '2019-07-01 13:30', editable: true },//可以拖動但不能縮放,但在周、日視圖中是可以進(jìn)行縮放的 { title : '可以拖動、縮放', start : '2019-07-02 00:00', end : '2019-07-02 23:59', color:'red', editable: true }, //可以拖動、縮放 { title : 'event 2', start : '2019-07-02', end : '2019-07-02', color:'red', editable: true }, { title: 'event 1', date: '2020-06-01', classNames:['cal'], editable: true }, { start: '2020-07-24', end: '2020-07-28', overlap: false, display: 'background', color: '#ff9f89' },//背景色 (添加相同時(shí)間的背景色時(shí)顏色會重疊) 一點(diǎn)要初始化日期時(shí)間 initialDate: '2020-07-10', ],
添加約束(日程只能在設(shè)置了 groupId: 'availableForMonthStart' 中進(jìn)行拖動以及縮放功能)
{ id: '添加約束', title: '添加約束', start: '2020-07-11 00:00', end: '2020-07-11 12:00', classNames: ['continuousClass'], color: '#75a7c8', editable: true, constraint: 'availableForMonthStart' }, { id: 'constraintDom', groupId: 'availableForMonthStart', start: '2020-07-11 00:00', end: '2020-07-11 23:59', display: 'background', color: '#ff9f89' }
自定義事件方法(dblClick)
在日歷事件方法看來難免還是會缺少部分方法的
這里我在日歷源碼中根據(jù)原先的點(diǎn)擊方法中復(fù)制了一個(gè)雙擊事件:
(這里根據(jù)原先的點(diǎn)擊事件添加dblclick就可以了)
// 添加雙擊事件 var EventDblClicking = /** @class */ (function (_super) { __extends(EventDblClicking, _super); function EventDblClicking(settings) { var _this = _super.call(this, settings) || this; _this.handleSegClick = function (ev, segEl) { var component = _this.component; var context = component.context; var seg = getElSeg(segEl); if (seg && // might be the <div> surrounding the more link component.isValidSegDownEl(ev.target)) { // our way to simulate a link dblclick for elements that can't be <a> tags // grab before trigger fired in case trigger trashes DOM thru rerendering var hasUrlContainer = elementClosest(ev.target, '.fc-event-forced-url'); var url = hasUrlContainer ? hasUrlContainer.querySelector('a[href]').href : ''; context.emitter.trigger('eventDblClick', { el: segEl, event: new EventApi(component.context, seg.eventRange.def, seg.eventRange.instance), jsEvent: ev, view: context.viewApi }); if (url && !ev.defaultPrevented) { window.location.href = url; } } }; _this.destroy = listenBySelector(settings.el, 'dblclick', '.fc-event', // on both fg and bg events _this.handleSegClick); return _this; } return EventDblClicking; }(Interaction));
(自定義方法添加就這三個(gè)地方)
自定義刪除標(biāo)簽:
考慮到日歷日程都是遍歷出來的,想通過在遍歷中添加標(biāo)簽這方法實(shí)屬麻煩
這邊采用的方法是修改源碼內(nèi)部添加刪除標(biāo)簽
?。ㄟ@邊添加后唯一的問題就是這個(gè)刪除標(biāo)簽的樣式,因?yàn)樗蟿踊蛘呖s放的時(shí)候還會有這個(gè)刪除按鈕,至于樣式處理我這邊就不詳細(xì)弄了,因?yàn)槲彝宋腋牧松稑邮剑?/p>
修改第一處(月視圖):
var StandardEvent = /** @class */ (function (_super) { __extends(StandardEvent, _super); function StandardEvent() { return _super !== null && _super.apply(this, arguments) || this; } StandardEvent.prototype.render = function () { var _a = this, props = _a.props, context = _a.context; var seg = props.seg; var timeFormat = context.options.eventTimeFormat || props.defaultTimeFormat; var timeText = buildSegTimeText(seg, timeFormat, context, props.defaultDisplayEventTime, props.defaultDisplayEventEnd); return (createElement(EventRoot, { seg: seg, timeText: timeText, disableDragging: props.disableDragging, disableResizing: props.disableResizing, defaultContent: props.defaultContent || renderInnerContent, isDragging: props.isDragging, isResizing: props.isResizing, isDateSelecting: props.isDateSelecting, isSelected: props.isSelected, isPast: props.isPast, isFuture: props.isFuture, isToday: props.isToday }, function (rootElRef, classNames, innerElRef, innerContent, hookProps) { return (createElement("a", __assign({ className: props.extraClassNames.concat(classNames).join(' '), style: { borderColor: hookProps.borderColor, backgroundColor: hookProps.backgroundColor }, ref: rootElRef }, getSegAnchorAttrs(seg)), // 手動添加了刪除標(biāo)簽 createElement("div", { className: 'fc-eventTooltip' }), createElement("a", { className: 'fc-eventDeleteClick' }, '刪除'), createElement("div", { className: 'fc-event-main', ref: innerElRef, style: { color: hookProps.textColor } }, innerContent,), hookProps.isStartResizable && createElement("div", { className: 'fc-event-resizer fc-event-resizer-start' }), hookProps.isEndResizable && createElement("div", { className: 'fc-event-resizer fc-event-resizer-end' },))); })); }; return StandardEvent; }(BaseComponent));
找到這部分代碼,然后替換掉
修改第二處(這部分是周、日視圖中的刪除,本來我想把刪除標(biāo)簽放到日程內(nèi)容下面,但周視圖中的樣式有點(diǎn)搞笑,會被撐下去,至于放那里,取決你們自己了):
// 手動添加了刪除標(biāo)簽 function renderInnerContent(innerProps) { return (createElement(Fragment, null, // createElement("div", { className: 'fc-daygrid-event-dot', style: { borderColor: innerProps.borderColor || innerProps.backgroundColor } }), innerProps.timeText && createElement("div", { className: 'fc-eventTooltip' }), createElement("a", { className: 'fc-eventDeleteClick' }, '刪除'), createElement("div", { className: 'fc-event-title' }, innerProps.event.title || createElement(Fragment, null, "\u00A0")), createElement("div", { className: 'fc-event-time' }, innerProps.timeText))); }
(替換掉后,是沒有點(diǎn)擊事件的,同上方自定義點(diǎn)擊事件一樣自己自定義就好了,這邊提示一下:不是所有隨便一個(gè)標(biāo)簽添加自定義事件都能成功的)
效果圖:
這邊我推薦幾個(gè)方法來修改樣式(這幾個(gè)方法都可以操作日程中的樣式):
eventDidMount: this.eventDidMount,// 渲染時(shí)
eventDragStart: this.eventDragStart, // 日程開始拖拽時(shí)觸發(fā)
eventDragStop: this.eventDragStop, // 日程拖拽結(jié)束時(shí)觸發(fā)
eventResizeStart: this.eventResizeStart, // 日程大小調(diào)整開始時(shí)觸發(fā)
eventResizeStop: this.eventResizeStop, // 日程大小調(diào)整結(jié)束時(shí)觸發(fā)
日歷選中方法(這里添加了一個(gè)選中日歷格后再次點(diǎn)擊日歷個(gè)后新增<雙擊日歷格>):
select: this.handleDateSelect
// 選中日歷格快速新增 handleDateSelect (selectInfo) { console.log(selectInfo) console.log(selectInfo.jsEvent.timeStamp) // 當(dāng)點(diǎn)擊兩次同日歷格時(shí)判斷(要第一次點(diǎn)擊選中之后在點(diǎn)擊才會生效) if ((moment(selectInfo.endStr).valueOf() - moment(selectInfo.startStr).valueOf() === 86400000 && moment(selectInfo.startStr).valueOf() >= moment(moment().format('YYYY-MM-DD')).valueOf() && selectInfo.view.type === 'dayGridMonth') || ((selectInfo.view.type === 'timeGridWeek' || selectInfo.view.type === 'timeGridDay') && moment(selectInfo.startStr).valueOf() >= moment(moment().format('YYYY-MM-DD')).valueOf() && (selectInfo.allDay ? (moment(selectInfo.endStr).valueOf() - moment(selectInfo.startStr).valueOf() === 86400000) : (moment(selectInfo.end).valueOf() - moment(selectInfo.start).valueOf() > 1800000)) )) { let temporaryTime = {} temporaryTime = { timeStamp: selectInfo.jsEvent.timeStamp, timeString: moment(selectInfo.start).format('YYYY-MM-DD') } // 第一次點(diǎn)擊時(shí)獲取選中 if (this.selectTimeStamp.length === 0) { this.selectTimeStamp.push({ timeStamp: selectInfo.jsEvent.timeStamp, timeString: moment(selectInfo.start).format('YYYY-MM-DD') }) } else { // 第二次點(diǎn)擊時(shí)判斷是否和第一次一樣,不一樣就刪除第一次的,添加第二次的 this.selectTimeStamp.forEach(item => { if (item.timeString === temporaryTime.timeString) { //內(nèi)容 } else { this.selectTimeStamp.splice(this.selectTimeStamp.findIndex(event => event.timeString === item.timeString), 1) this.selectTimeStamp.push({ timeStamp: selectInfo.jsEvent.timeStamp, timeString: moment(selectInfo.start).format('YYYY-MM-DD') }) } }) } } // 判斷過去時(shí)間不能新增 if ((moment(selectInfo.endStr).valueOf() - moment(selectInfo.startStr).valueOf() > 86400000 && moment(selectInfo.startStr).valueOf() < moment(moment().format('YYYY-MM-DD')).valueOf() && selectInfo.view.type === 'dayGridMonth') || ((selectInfo.view.type === 'timeGridWeek' || selectInfo.view.type === 'timeGridDay') && moment(selectInfo.startStr).valueOf() < moment(moment().format('YYYY-MM-DD')).valueOf() && (selectInfo.allDay ? (moment(selectInfo.endStr).valueOf() - moment(selectInfo.startStr).valueOf() > 86400000) : (moment(selectInfo.end).valueOf() - moment(selectInfo.start).valueOf() > 1800000)) )) { this.$confirm({ title: '提示', content: '過去時(shí)間不能進(jìn)行新增!', okText: '確定', cancelText: '取消', onOk () { } }) } // 判斷獲取的時(shí)間大于當(dāng)前、以及兩天以上 if ((moment(selectInfo.endStr).valueOf() - moment(selectInfo.startStr).valueOf() > 86400000 && moment(selectInfo.startStr).valueOf() >= moment(moment().format('YYYY-MM-DD')).valueOf() && selectInfo.view.type === 'dayGridMonth') || ((selectInfo.view.type === 'timeGridWeek' || selectInfo.view.type === 'timeGridDay') && moment(selectInfo.startStr).valueOf() >= moment(moment().format('YYYY-MM-DD')).valueOf() && (selectInfo.allDay ? (moment(selectInfo.endStr).valueOf() - moment(selectInfo.startStr).valueOf() > 86400000) : (moment(selectInfo.end).valueOf() - moment(selectInfo.start).valueOf() > 1800000)) )) { //內(nèi)容 } },
效果圖:
這里我給到一個(gè)文檔的參考event事件鉤子:
Events and Hooks
- event-selected(event, jsEvent, view) - Triggered on eventClick()
- event-mouseover(event, jsEvent, view) - Triggered on eventMouseover()
- event-mouseout(event, jsEvent, view) - Triggered on eventMouseout()
- event-drop(event) - Triggered on eventDrop()
- event-resize(event) - Triggered on eventResize()
- event-created(event) - Triggered on select()
- event-receive(event) - Triggered on eventReceive()
- event-render(event) - Triggered on eventRender()
- view-render(view, element) - Triggered on viewRender()
- day-click(date, jsEvent, view) - Triggered on dayClick()
擴(kuò)展--------------------------------------------
1、月視圖增加農(nóng)歷
calendarOptions中增加views數(shù)據(jù);
通過dayCellContent來設(shè)置日期里顯示的數(shù)據(jù);
引入calendar.js計(jì)算農(nóng)歷 https://github.com/jjonline/calendar.js;
import calenderFormate from "../utils/calendar" //農(nóng)歷計(jì)算方法 import {formatDate} from "../utils/index" //將日期對象轉(zhuǎn)換成 2020-01-01 格式的日期 //data中calendarOptions修改: calendarOptions: { views:{ //對應(yīng)月視圖 dayGridMonth:{ displayEventTime:false,//是否顯示時(shí)間 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、周視圖增加農(nóng)歷
在前面的基礎(chǔ)上修改views;
在dayHeaderContent中設(shè)置顯示數(shù)據(jù);
views: { //對應(yīng)周視圖調(diào)整 timeGridWeek:{ slotMinTime:"09:00",//周視圖開始時(shí)間 slotMaxTime:"20:00",//周視圖結(jié)束時(shí)間 displayEventTime:false,//是否顯示時(shí)間 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>`} } } }
效果圖:
推薦參考的文檔:
https://www.npmjs.com/package/vue-full-calendar
https://blog.csdn.net/supingemail/article/details/48371927
(這里我提一下,一般在git提交代碼的時(shí)候,修改的源碼是不能提上去的,要手動打包過去)
(這邊我暫時(shí)就添加了我個(gè)人覺得夠用的,只是部分沒詳細(xì)解釋,我想起來的話會更新的,如果有什么問題可以在下面留言)
到此這篇關(guān)于fullCalendar日歷插件玩法解析的文章就介紹到這了,更多相關(guān)fullCalendar日歷插件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于Javascript加載執(zhí)行優(yōu)化的研究報(bào)告
這篇文章主要介紹了關(guān)于Javascript加載執(zhí)行優(yōu)化的研究報(bào)告,需要的朋友可以參考下2014-12-12全面解析Bootstrap中form、navbar的使用方法
這篇文章主要為大家詳細(xì)解析了Bootstrap中form、navbar的使用方法,感興趣的朋友可以參考一下2016-05-05對 lightbox JS 圖片控件進(jìn)行了一下改造, 使其他支持復(fù)雜的圖片說明
如果要為圖片添加詳細(xì)的圖片說明,并為圖片的說明設(shè)置一些格式,如字體的大小、顏色等,那么使用 title 這個(gè)屬性來設(shè)置這些說明信息是沒辦法實(shí)現(xiàn)的。2010-03-03element-ui?對話框dialog使用echarts報(bào)錯(cuò)'dom沒有獲取到'的問題
這篇文章主要介紹了element-ui?對話框dialog里使用echarts,報(bào)錯(cuò)'dom沒有獲取到'的問題,在這個(gè)事件里邊進(jìn)行echarts的初始化,執(zhí)行數(shù)據(jù),本文結(jié)合實(shí)例代碼給大家詳細(xì)講解,需要的朋友可以參考下2022-11-11Bootstrap3 多個(gè)模態(tài)對話框無法顯示的解決方案
這篇文章主要介紹了Bootstrap3 多個(gè)模態(tài)對話框無法顯示的解決方案,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-02-02JavaScript判斷兩個(gè)對象是否相等的方法總結(jié)
判斷兩個(gè)對象是否相等是js中的一個(gè)很常見的內(nèi)容,不同的編程語言和環(huán)境可能會有不同的方式來實(shí)現(xiàn)這一目標(biāo),在 JavaScript 中,判斷兩個(gè)對象是否相等主要有以下幾種方法,感興趣的小伙伴跟著小編一起來看看吧2024-08-08