关于宇宙最强日历插件fullcalendar在vue3中的实现-包含外部拖拽

3,832 阅读2分钟

vue 版本3.2.45 fullcalendar及插件 版本6.1.7 样式使用的是tailwindcss,可使用内联样式,效果一样的

1.安装fullcalendar插件

必须安装的插件:

npm install @fullcalendar/core

npm install @fullcalendar/vue3

必须安装一个:

npm install @fullcalendar/daygrid

npm install @fullcalendar/multimonth

npm install @fullcalendar/timegrid

拖拽必须安装的插件:

npm install @fullcalendar/interaction

vue文件中引用

import FullCalendar from "@fullcalendar/vue3"

汉化时必须引入:

import locale from "@fullcalendar/core/locales/zh-cn"

拖拽时需引入

import interactionPlugin, { Draggable } from "@fullcalendar/interaction"

template端

 <fullCalendar :option="calendarOptions" style="width:100%" ref="fullcalendarref" />

template端 需要拖动的div

 <div
     class="h-[350px] space-y-2"
     id="eventListItems"
     ref="eventListItems"
 >
     <div
         v-for="(item,index) in eventList"
         class="rounded p-1 text-white pl-2 eventListItems"
         :class="item.colorclass"
         :draggable="true"
         :key="index"
         :id="item.eventId"
     >
          <span :id="item.color">{{ item.eventName }}</span>
     </div>
 </div>

script setup中编写option具体参数意义已注释,也可以查看fullcalendar.io/docs#toc

 const calendarOptions = ref({
   plugins: [multiMonthPlugin, dayGridPlugin,interactionPlugin, timeGridPlugin],//需要加载的插件               initialView: "dayGridMonth", //初始视图
   multiMonthMaxColumns: 3,//多月展示时最多几个月一行
   height: "780px",
   locale: locale, //语言汉化
   selectable: true, 
   editable: true, 
   droppable: true,
   dropAccept: ".eventListItems", //可被拖进
   dayMaxEventRows: 2.0, //事件最大展示列数
   fixedWeekCount: false, //因为每月起始日是星期几不固定,导致一个月的行数会不固定,是否固定行数
   drop: dropItem, //外部拖拽进的事件方法
   handleWindowResize: true,
   windowResizeDelay: 100,
   aspectRatio: 2, //宽高比
   headerToolbar: {
     left: "prevYear,prev,next,nextYear today",
     center: "title",
     right: "multiMonthYear,dayGridMonth,timeGridWeek,timeGridDay"
   }, //日历上方的按钮和title
   events: matchList.value, //绑定展示事件
   dateClick: info => {
     console.log(info);
   },//点击日期info是单元格的信息
   eventClick: info => {
     console.log(info);
     dialogVisible.value = true;
   } //事件的点击
 });

日历绑定需要展示的事件数组

 const matchList = ref([
   {
     id: "1",
     title: "第一个任务",
     start: "2023-05-26 13:22:24",
     allDay: true,
     color: "#FECACA",
     textColor: "#6B7280"
   },
   {
     id: "11",
     title: "第二个任务",
     start: "2023-05-26 13:22:24",
     allDay: true,
     color: "#6EE7B7"
   },
   {
     id: "12",
     title: "第三个任务",
     start: "2023-05-26 13:22:24",
     allDay: true,
     color: "#93C5FD"
   },
   {
     id: "13",
     title: "劳动节",
     start: "2023-05-01 00:00:00",
     allDay: true,
     color: "#F59E0B",
     editable: false
   },
   {
     id: "2",
     title: "第二个任务",
     start: "2023-05-27 13:22:24",
     end: "2023-04-27 23:22:24",
     allDay: true,
     color: "#FBCFE8"
   },
   {
     id: "4",
     title: "第三个任务",
     start: "2023-05-28 13:22:24",
     end: "2023-04-28 23:22:24",
     allDay: true,
     color: "#EDE9FE"
   }
 ]);

原生拖拽的开启

 onMounted(() => {
   new Draggable(eventListItems.value, {
     itemSelector: ".eventListItems"
   });
 });

最后关于拖拽函数数据的处理

将需要的数据已对象的形式push到绑定的事件数组中

 const dropItem = info => {
   const obj = {
     title: info.draggedEl.firstChild.innerHTML,
     id: info.draggedEl.id,
     start: info.dateStr,
     allDay: true,
     color: info.draggedEl.firstChild.id,
     editable: true
   };
   matchList.value.push(obj);
 };

最终的效果

企业微信截图_16855185658320.png