了解Vue中日历插件Fullcalendar

实现效果如下图:

月视图
了解Vue中日历插件Fullcalendar_第1张图片

了解Vue中日历插件Fullcalendar_第2张图片
周视图
了解Vue中日历插件Fullcalendar_第3张图片
日视图
了解Vue中日历插件Fullcalendar_第4张图片

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

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

npm install --save @fullcalendar/vue @fullcalendar/core @fullcalendar/daygrid @fullcalendar/timegrid @fullcalendar/list
npm install --save @fullcalendar/interaction
npm install --save @fullcalendar/core @fullcalendar/resource-timeline

2.使用日历的页面需要导入

import FullCalendar from "@fullcalendar/vue";
import dayGridPlugin from "@fullcalendar/daygrid";
import timeGridPlugin from "@fullcalendar/timegrid";
import listPlugin from "@fullcalendar/list";
import interactionPlugin from "@fullcalendar/interaction";
// import resourceTimelinePlugin from "@fullcalendar/resource-timeline";

完整代码

<template>
  <div>
    <div class="fc-toolbar">
      <div class="fc-left">
        <el-button-group>
          <el-button @click="month"></el-button>
          <el-button @click="week"></el-button>
          <el-button @click="today"> 今天 </el-button>
        </el-button-group>
      </div>
      <div class="fc-center">
        <el-button icon="el-icon-arrow-left" @click="prev"/>
        <p class="title">
          {{ title }}
        </p>
        <el-button icon="el-icon-arrow-right" @click="next" />
      </div>
      <div>
        <el-select v-model="type" style="margin-right: 20px" @change="handleType">
          <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
        <el-button class="search" style="margin-right: 20px" type="button" @click="addEvent">
          新增
        </el-button>
        <el-button class="search" type="button" @click="search">
          查询
        </el-button>
      </div>
    </div>
    <el-dialog title="添加日程" :visible.sync="dialogFormVisible" width="600px">
      <el-form :model="form">
        <el-form-item label="事件">
          <el-input v-model="form.content" autocomplete="off" placeholder="请输入事件"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="navConfirm">确 定</el-button>
      </div>
    </el-dialog>
    <div v-if="showFullcalendar">加载数据中......</div>
    <FullCalendar v-else 
      id="calendar" 
      ref="fullCalendar" 
      class="demo-app-calendar" 
      :options="calendarOptions"
     >
      <template v-slot:eventContent="arg">
        <el-popover placement="top-start" title="标题" width="200" :visible-arrow="false" trigger="click">
          <i class="title">{{ arg.event.title }}</i>
          <el-button @click="more(arg.event)"> 更多 </el-button>
          <div slot="reference" class="popper-content">
            <span>{{ arg.timeText }}</span>
            <i>{{ arg.event.title }}</i>
          </div>
        </el-popover>
      </template>
      <template v-slot:dayCellContent="arg">
        {{ arg.dayNumberText }}
      </template>
      <template v-slot:resourceLabelContent="arg">
        {{ arg.resource.id }}
      </template>
    </FullCalendar>
  </div>
</template>
<script>
	import FullCalendar from "@fullcalendar/vue";
	import dayGridPlugin from "@fullcalendar/daygrid";
	import timeGridPlugin from "@fullcalendar/timegrid";
	import listPlugin from "@fullcalendar/list";
	import interactionPlugin from "@fullcalendar/interaction";
	// import resourceTimelinePlugin from "@fullcalendar/resource-timeline";
	
	let clickCount = 0;
	let prev = ""; // 上一次点击的dom节点
	export default {
	  components: {
	    FullCalendar, // make the  tag available
	  },
	  data() {
	    return {
	      showFullcalendar: true,
	      title: "",
	      currentView: {},
	      options: [
	        { value: "timeline", label: "resource-timeline" },
	        { value: "dategrid", label: "agenda" },
	      ],
	      type: "dategrid",
	      calendarOptions: {
	        locale: "zh",
	        timeZone: "UTC",
	        plugins: [
	          dayGridPlugin,
	          timeGridPlugin,
	          listPlugin,
	          // resourceTimelinePlugin,
	          interactionPlugin,
	        ],
	        buttonText: {
	          // 设置按钮
	          today: "今天",
	          month: "月",
	          week: "周",
	          dayGrid: "天",
	        },
	        initialView: "dayGridMonth", // 设置默认显示月,可选周、日
	        resourceAreaWidth: 200,
	        contentHeight: 600,
	        slotMinWidth: 70,
	        resourceOrder: "number",
	        editable: true,
	        dayMaxEvents: true, // allow "more" link when too many events
	        eventDurationEditable: true, // 可以调整事件的时间
	        selectable: true, // 日历格子可选择
	        nowIndicator: true, // 现在的时间线显示
	        eventDisplay: "block", // 争对全天的情况下,以块状显示
	        headerToolbar: false, // 隐藏头部的导航栏
	        selectMirror: false,
	        displayEventEnd: true, // like 08:00 - 13:00
	        eventTimeFormat: {
	          // like '14:30:00'
	          hour: "2-digit",
	          minute: "2-digit",
	          meridiem: false,
	          hour12: false, // 设置时间为24小时
	        },
	        events: [],
	        eventColor: "#378006",
	        allDayText: "全天",
	        dateClick: this.handleDateClick, //点击日程事件
	        eventClick: this.handleEventClick,  //点击日历中的某一日程
	        select:this.handleDateSelect, // 监听用户选择的时间段,
	        eventDrop:this.handleEventDrop,  //监听事件被拖动的操作
	        eventResize:this.handleEventResize, //监听事件调整大小的操作
	        resourceAreaHeaderContent: "Rooms",
	        resources: [
	          {
	            id: "111",
	            title: "asas",
	            number: 1,
	          },
	        ],
	        schedulerLicenseKey: "GPL-My-Project-Is-Open-Source",
	        resourceLabelContent(arg) {
	          return {
	            html: `
id: ${arg.resource.id}
title: ${arg.resource.title}
`
, }; }, views: { customTimeLineWeek: { type: "resourceTimeline", duration: { weeks: 1 }, slotDuration: { days: 1 }, buttonText: "Custom Week", slotLabelFormat: { weekday: "long", // month: 'numeric', // day: 'numeric', omitCommas: true, }, }, customTimeLineMonth: { type: "resourceTimeline", duration: { month: 1 }, slotLabelFormat: { // month: 'numeric', day: "numeric", // omitCommas: true, }, }, customGridWeek: { type: "timeGridWeek", dayHeaderFormat: { weekday: "long", }, slotLabelFormat: { // 左侧时间格式 hour: "2-digit", minute: "2-digit", meridiem: "lowercase", hour12: false, // false设置时间为24小时 }, }, }, // 切换视图调用的方法 datesSet() { }, }, calendarApi: null, monthEvent: [ { id: "1", resourceId: "1", title: "待办", start: "2024-01-04 09:00", end: "2024-01-04 18:00", color: "red", }, { resourceId: "2", id: "2", title: "待办", start: "2024-01-15", color: "purple", }, { title: "待办", start: "2024-01-09" }, { title: "待办", start: "2024-01-17" }, { title: "待办", start: "2024-01-07" }, { title: "待办", start: "2024-01-07", color: "pink" }, { title: "待办", start: "2024-01-07" }, { title: "待办", start: "2024-01-07" }, { id: "3", resourceId: "number_3", title: "待办", start: "20240111", end: "20240113", color: "blue", extendedProps: { description: "测试测试测试测试", }, }, { id: 4, title: "待办", start: "2024-01-15", extendedProps: { description: "test test test test test", }, }, ], weekEvent: [ { id: "4", resourceId: "4", title: "周待办", start: "2024-01-11", color: "red", }, { id: "5", resourceId: "5", title: "待办1", start: "2024-01-04 10:00", end: "2024-01-04 18:00", color: "orange", }, ], dayDate:'', dialogFormVisible:false, form:{ content:'', }, selectInfo:{}, }; }, mounted() { setTimeout(() => { this.showFullcalendar = false; this.$nextTick(() => { this.calendarApi = this.$refs.fullCalendar.getApi(); this.title = this.calendarApi.view.title; this.getDtata(); }); }, 1000); }, watch: { // 切换视图显示不同的事件 "calendarApi.view.type"(newVal) { this.getDtata(); }, }, methods: { // 监听用户选择的时间段,当用户选择了一段时间后会触发该回调,可以在这里处理创建新的日程。 handleDateSelect(selectInfo) { console.log('selectInfo: ', selectInfo); this.selectInfo = selectInfo; this.form.content = ''; // 用户选择了一个日期范围时触发 this.dialogFormVisible = true; }, // 用户拖动移动事件时触发 handleEventDrop(dropInfo) { console.log('dropInfo: ', dropInfo); const updatedEvent = { ...dropInfo.event }; updatedEvent.start = dropInfo.revertDuration ? dropInfo.oldEvent.start : dropInfo.event.start; updatedEvent.end = dropInfo.event.end; // 更新服务器上的事件或者重新排序你的事件数组 // 示例:this.updateEventOnServer(updatedEvent); // 如果是在内存中维护事件,则更新本地数据 const index = this.events.findIndex(e => e.id === updatedEvent.id); if (index !== -1) { this.events.splice(index, 1, updatedEvent); } }, // 用户调整事件长度时触发 handleEventResize(resizeInfo) { console.log('resizeInfo: ', resizeInfo); const updatedEvent = { ...resizeInfo.event }; updatedEvent.end = resizeInfo.event.end; // 同样更新服务器或本地数据 // 示例:this.updateEventOnServer(updatedEvent); const index = this.events.findIndex(e => e.id === updatedEvent.id); if (index !== -1) { this.events.splice(index, 1, updatedEvent); } }, getDtata() { setTimeout(() => { this.calendarOptions.events = this.calendarApi.view.type === "dayGridMonth" ? this.monthEvent : this.weekEvent; }, 200); }, // 点击更多 more(e) { console.log('more ', e) }, //确认弹框按钮 navConfirm(){ this.dialogFormVisible = false; if (this.form.content) { this.calendarOptions.events.push({ title: this.form.content, start: this.selectInfo.startStr, end: this.selectInfo.endStr, }); // 更新日历视图以显示新添加的事件 this.$refs.fullCalendar.getApi().addEvent({ //等同于 this.calendarApi.addEvent title: this.form.content, start: this.selectInfo.startStr, end: this.selectInfo.endStr, }); } }, // 增加事件 addEvent() { this.form.content = ''; this.dialogFormVisible = true; // this.monthEvent }, //点击日历中的某一日程 handleEventClick(clickInfo) { console.log('clickInfo:', clickInfo); // 用户点击事件时触发,用于编辑或删除事件 const event = clickInfo.event; console.log('Clicked on:', event.title); // 这里可以弹出模态框进行编辑或调用删除函数等操作 }, // 单击事件(日历中的某一天) handleDateClick(e) { this.dayDate = e.dateStr; if (e.dateStr !== prev) { clickCount = 0; } clickCount += 1; prev = e.dateStr; setTimeout(() => { if (clickCount === 2) { console.log("db click"); } else if (clickCount === 1) { console.log("one click"); } clickCount = 0; }, 300); }, // 切换 prev() { this.calendarApi.prev(); this.title = this.calendarApi.view.title; }, next() { this.calendarApi.next(); this.title = this.calendarApi.view.title; }, // 今天 today(date, jsEvent, view) { // if (this.type === "timeline") { // this.calendarApi.changeView("customTimeLineWeek"); // } else { // this.calendarApi.changeView("customGridWeek"); // } this.calendarApi.today(); this.title = this.calendarApi.view.title; this.calendarApi.changeView("timeGridDay"); // this.calendarApi.today(); // this.title = this.calendarApi.view.title; }, // 月 month() { if (this.type === "timeline") { this.calendarApi.changeView("customTimeLineMonth"); } else { this.calendarApi.changeView("dayGridMonth"); } this.calendarApi.today(); this.title = this.calendarApi.view.title; }, // 周 week() { if (this.type === "timeline") { this.calendarApi.changeView("customTimeLineWeek"); } else { this.calendarApi.changeView("customGridWeek"); } this.calendarApi.today(); this.title = this.calendarApi.view.title; }, // 天 day() { this.calendarApi.today(); this.title = this.calendarApi.view.title; }, // 查询 search() { this.calendarApi.changeView("dayGrid", { start: "2022-07-07", end: "2022-07-09", }); }, // 选择时间线、日程 handleType() { if (this.type === "timeline") { this.calendarApi.changeView("customTimeLineMonth"); this.calendarOptions.slotLabelFormat = null; } else { this.calendarApi.changeView("dayGridMonth"); } }, }, }; </script> <style scoped> .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; } .fc-toolbar { width: 100%; margin: 30px auto; display: flex; flex: 1; justify-content: space-around; align-content: center; } .fc-center { /* height: 40px; */ display: flex; align-content: center; } .fc-center .title { font-size: 16px; padding: 0 15px; font-weight: 700; /* height: 40px; */ /* line-height: 40px; */ } </style>

你可能感兴趣的:(vue.js,elementui,前端)