FullCalendar日历插件在Vue3中的简单使用

写在前面的话

由于近日公司项目要升级使用Vue3,很多插件就需要去更新版本,首先想到的就是FullCalendar日历插件,于是便去对应的官网查看插件是否支持Vue3,结果 o(╥﹏╥)o 官方暂时还没更新Vue3.0版本,紧接着去github上查看大神们的解决方案,皇天不负有心人,找到了部分大神们的意见【文档地址一】【文档地址二】,可以前往查看,我在这里稍微整理了一下,使得FullCalendar插件可以在Vue3中正常运行

1、Vue版本和FullCalendar版本

“vue”: “^3.0.0” “@fullcalendar/core”: “^5.6.0″,”@fullcalendar/daygrid”: “^5.6.0″,”@fullcalendar/interaction”: “^5.6.0″,”@fullcalendar/timegrid”: “^5.6.0″,”@fullcalendar/vue”: “^5.6.0”,

 

2、安装

npm install –save @fullcalendar/vue @fullcalendar/core @fullcalendar/daygrid @fullcalendar/interaction @fullcalendar/timegrid

3、修改custom-content-type.js文件

找到安装之后的文件,文件路径为\node_modules\@fullcalendar\vue\dist\custom-content-type.js

import { createPlugin } from ‘@fullcalendar/core’import { createApp } from ‘vue’/*wrap it in an object with a `vue` key, which the custom content-type handler system will look for*/export function wrapVDomGenerator(vDomGenerator) { return function (props) { return { vue: vDomGenerator(props) } }}export function createVueContentTypePlugin(parent){ return createPlugin({ contentTypeHandlers: { vue: function () { return buildVDomHandler(parent); }, } });}function buildVDomHandler() { let currentEl let v // the Vue instance return function (el, vDomContent) { // the handler if (currentEl !== el) { if (currentEl && v) { // if changing elements, recreate the vue v.$destroy() } currentEl = el } if (!v) { v = initVue(vDomContent) // vue’s mount method *replaces* the given element. create an artificial inner el let innerEl = document.createElement(‘span’) el.appendChild(innerEl) v.$mount(innerEl) } else { v.content = vDomContent } }}function initVue(initialContent) { return createApp({ props: { content: Array }, propsData: { content: initialContent }, render(h) { let { content } = this // the slot result can be an array, but the returned value of a vue component’s // render method must be a single node. if (content.length === 1) { return content[0] } else { return h(‘span’, {}, content) } } })}

4、修改FullCalendar.js文件

找到安装之后的文件,文件路径为\node_modules\@fullcalendar\vue\dist\FullCalendar.js

import { __assign } from “tslib”;import {defineComponent,h} from ‘vue’;import { Calendar } from ‘@fullcalendar/core’;import { OPTION_IS_COMPLEX } from ‘./options’;import { shallowCopy, mapHash } from ‘./utils’;import { wrapVDomGenerator, createVueContentTypePlugin } from ‘./custom-content-type’;const FullCalendar={ props: { options: Object }, data: initData, render(){ return h(‘div’, { // when renderId is changed, Vue will trigger a real-DOM async rerender, calling beforeUpdate/updated attrs: { ‘data-fc-render-id’: this.renderId } }); }, mounted: function () { var internal = this.$options; internal.scopedSlotOptions = mapHash(this.$scopedSlots, wrapVDomGenerator); // needed for buildOptions var calendar = new Calendar(this.$el, this.buildOptions(this.options, this)); internal.calendar = calendar; calendar.render(); }, methods: { getApi: getApi, buildOptions: buildOptions, }, beforeUpdate: function () { this.getApi().resumeRendering(); // the watcher handlers paused it }, beforeDestroy: function () { this.getApi().destroy(); }, watch: buildWatchers()};function initData() { return { renderId: 0 };}function buildOptions(suppliedOptions, parent) { var internal = this.$options; suppliedOptions = suppliedOptions || {}; // return __assign(__assign(__assign({}, internal.scopedSlotOptions), suppliedOptions), { plugins: (suppliedOptions.plugins || []).concat([ // createVueContentTypePlugin(parent) // ]) }); return { …internal.scopedSlotOptions, …suppliedOptions, // spread will pull out the values from the options getter functions plugins: (suppliedOptions.plugins || []).concat([ createVueContentTypePlugin(parent) ]) }}function getApi() { var internal = this.$options; return internal.calendar;}function buildWatchers() { var watchers = { // watches changes of ALL options and their nested objects, // but this is only a means to be notified of top-level non-complex options changes. options: { deep: true, handler: function (options) { var calendar = this.getApi(); calendar.pauseRendering(); calendar.resetOptions(this.buildOptions(options, this)); this.renderId++; // will queue a rerender } } }; var _loop_1 = function (complexOptionName) { // handlers called when nested objects change watchers[“options.” + complexOptionName] = { deep: true, handler: function (val) { var _a; // unfortunately the handler is called with undefined if new props were set, but the complex one wasn’t ever set if (val !== undefined) { var calendar = this.getApi(); calendar.pauseRendering(); calendar.resetOptions((_a = {}, // the only reason we shallow-copy is to trick FC into knowing there’s a nested change. // TODO: future versions of FC will more gracefully handle event option-changes that are same-reference. _a[complexOptionName] = shallowCopy(val), _a), true); this.renderId++; // will queue a rerender } } }; }; for (var complexOptionName in OPTION_IS_COMPLEX) { _loop_1(complexOptionName); } return watchers;}export default defineComponent(FullCalendar);

5、修改完上面两个文件之后,就可以进行测试了

import FullCalendar from “@fullcalendar/vue”;import dayGridPlugin from “@fullcalendar/daygrid”;import timeGridPlugin from “@fullcalendar/timegrid”;import interactionPlugin from “@fullcalendar/interaction”;export default { components: { FullCalendar, // make the tag available }, data: function () { return { calendarOptions: { allDayText: “全天”, buttonText: { today: “今天”, month: “月视图”, week: “周视图”, day: “天视图”, list: “列表”, }, locale: “zh-cn”, weekMode: “variable”, plugins: [ dayGridPlugin, timeGridPlugin, interactionPlugin, // needed for dateClick ], headerToolbar: { left: “prev,next today”, center: “title”, right: “dayGridMonth,timeGridWeek,timeGridDay”, }, initialView: “dayGridMonth”, initialEvents: [ { id: this.createEventId(), title: “All-day event”, start: new Date().toISOString().replace(/T.*$/, “”) + “T12:00:00”, }, { id: this.createEventId(), title: “Timed event”, start: new Date().toISOString().replace(/T.*$/, “”) + “T12:00:00”, }, ], // alternatively, use the `events` setting to fetch from a feed editable: true, selectable: true, selectMirror: true, dayMaxEvents: true, weekends: true, select: this.handleDateSelect, eventClick: this.handleEventClick, eventsSet: this.handleEvents, /* you can update a remote database when these fire: eventAdd: eventChange: eventRemove: */ }, currentEvents: [], eventGuid: 0, }; }, methods: { handleWeekendsToggle() { this.calendarOptions.weekends = !this.calendarOptions.weekends; // update a property }, 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: this.createEventId(), title, start: selectInfo.startStr, end: selectInfo.endStr, allDay: selectInfo.allDay, }); } }, handleEventClick(clickInfo) { if ( confirm( `Are you sure you want to delete the event ‘${clickInfo.event.title}’` ) ) { clickInfo.event.remove(); } }, handleEvents(events) { this.currentEvents = events; }, createEventId() { return String(this.eventGuid++); }, }, mounted() { this.initialEvents = [ { id: this.createEventId(), title: “All-day event”, start: this.todayStr, }, { id: this.createEventId(), title: “Timed event”, start: this.todayStr + “T12:00:00”, }, ]; },}; Instructions Select dates and you will be prompted to create a new event Drag, drop, and resize events Click an event to delete it toggle weekends All Events ({{ currentEvents.length }}) {{ event.startStr }} {{ event.title }} {{ arg.timeText }} {{ arg.event.title }} h2 { margin: 0; font-size: 16px;}ul { margin: 0; padding: 0 0 0 1.5em;}li { margin: 1.5em 0; padding: 0;}b { /* used for event dates/times */ margin-right: 3px;}.demo-app { display: flex; min-height: 100%; font-family: Arial, Helvetica Neue, Helvetica, sans-serif; font-size: 14px;}.demo-app-sidebar { width: 300px; line-height: 1.5; background: #eaf9ff; border-right: 1px solid #d3e2e8;}.demo-app-sidebar-section { padding: 2em;}.demo-app-main { flex-grow: 1; padding: 3em;}.fc { /* the calendar root */ max-width: 1100px; margin: 0 auto;}

6、运行界面

 

由于每次重新安装FullCalendar插件之后都需要重新修改一遍文件,这里就不提供案例了

平时积累,用于复习,如有问题,请留言,谢谢

 


比丘资源网 » FullCalendar日历插件在Vue3中的简单使用

发表回复

提供最优质的资源集合

立即查看 了解详情