了解Vue中日历插件Fullcalendar

news2024/11/15 12:48:11

实现效果如下图:

月视图
在这里插入图片描述

在这里插入图片描述
周视图
在这里插入图片描述
日视图
在这里插入图片描述

官方文档地址: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 <FullCalendar> 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: `<div>id: ${arg.resource.id}</div><div>title: ${arg.resource.title}</div>`,
	          };
	        },
	        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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1397490.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL复合查询 内外连接

目录 前言&#xff1a; 多表查询&#xff1a; 显示部门号为10的部门名&#xff0c;员工名和工资 : 显示各个员工的姓名&#xff0c;工资&#xff0c;及工资级别: 自连接 显示员工FORD的上级领导的编号和姓名(mgr是员工领导的编号&#xff09; 子查询 单行子查询&#…

IPv6自动隧道---6to4中继

6to4中继 普通IPv6网络需要与6to4网络通过IPv4网络互通,这可以通过6to4中继路由器方式实现。所谓6to4中继,就是通过6to4隧道转发的IPv6报文的目的地址不是6to4地址,但转发的下一跳是6to4地址,该下一跳为路由器我们称之为6to4中继。隧道的IPv4目的地址依然从下一跳的6to4地…

电池容量常见测试方法分享 -纳米软件

电池容量是衡量电池性能的重要指标之一&#xff0c;它是指电池在一定条件下放出的电量&#xff0c;可以用于帮助评估电池的性能和寿命。那么如何快速测试电池容量呢? 一、用万用表测试 用万用表测试电池容量&#xff0c;需要将万用表调整到电容模式&#xff0c;然后连接电池到…

鸿蒙HarmonyOS实战-ArkTS语言(基本语法)

&#x1f680;一、ArkTS语言基本语法 &#x1f50e;1.简介 HarmonyOS的ArkTS语言是一种基于TypeScript开发的语言&#xff0c;它专为HarmonyOS系统开发而设计。ArkTS语言结合了JavaScript的灵活性和TypeScript的严谨性&#xff0c;使得开发者能够快速、高效地开发出高质量的Har…

mac PyCharm 上传文件到远程服务器+远程服务器下载到本地

1 部署配置 选择SFTP name&#xff1a;test6 输入ssh账号和密码。保存密码和30s心跳。 2 目录映射 Local path&#xff08;本地mac机器&#xff09;&#xff1a;/Users/clevercode/PycharmProjects/test6 Root path&#xff08;远程服务机器&#xff09;&#xff1a;/home/…

Redis持久化方案RDB和AOF

Redis两种持久化方案 RDB持久化AOF持久化 RDB持久化 RDB全称Redis Database Backup file&#xff08;Redis数据备份文件&#xff09;&#xff0c;也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后&#xff0c;从磁盘读取快照文…

【stm32】hal库学习笔记-GPIO按键控制LED和蜂鸣器(超详细!)

【stm32】hal库学习笔记-GPIO按键控制LED和蜂鸣器 注&#xff1a;本学习笔记基于stm32f4系列 使用的开发板为正点原子stmf407ZGT6探索者开发板 GPIO引脚使用时&#xff0c;可输入或输出数字信号 例如: 检测按键输入信号&#xff08;Read_Pin&#xff09;输出信号&#xff08;W…

PHP面试小结(20240108)

PHP 部分 1. php的包管理工具是如何实现自动加载的 换句话问&#xff1a;composer 实现原理是什么&#xff1f;spl_autoload_register() 首先&#xff0c;Composer 是 PHP 的一个包管理和包依赖管理的工具 &#xff0c; 打开安装之后生成的 "vendor" 文件, 里面有个…

Spring Boot 的约定优于配置,你的理解是什么?

对于 Spring Boot 约定优于配置 这个问题&#xff0c;看看高手是如何回答的&#xff1f; 一、问题解析 我从 4 个点方面来回答。 1. 首先&#xff0c; 约定优于配置是一种软件设计的范式&#xff0c;它的核心思想是减少软件开发人员对于配置项的维护&#xff0c;从而让开发人…

Windows如何给已经启动的Docker容器添加或者修改端口映射(通过修改配置文件实现)

需求&#xff1a;已经启动的Docker容器添加或者修改端口映射 找到配置文件&#xff1a; \wsl.localhost\docker-desktop-data*data*\docker\containers[hash_of_the_container] 有些版本在&#xff1a; \wsl$\docker-desktop-data*version-pack-data*\community\docker\contai…

Linux编辑器---vim

目录 1、vim的基本概念 2正常/普通/命令模式(Normal mode) 2、1命令模式下一些命令&#xff08;不用进入插入模式&#xff09; 3插入模式(Insert mode) 4末行/底行模式(last line mode) 4、1底行模式下的一些命令 5、普通用户无法进行sudo提权的解决方案 6、vim配置问题 6、1配…

计算机找不到msvcr100.dll无法继续执行的5种解决方法,实测有效

“msvcr100.dll文件丢失这一问题&#xff0c;时常给计算机用户带来诸多困扰与不便。作为Microsoft Visual C运行库中的一个关键动态链接库文件&#xff0c;msvcr100.dll在系统和应用程序的正常运行中扮演着不可或缺的角色。一旦该文件发生丢失或损坏&#xff0c;可能会引发一系…

基于easyexcel实现导出excel,包括导出图片以及导出下拉框

基于easyexcel实现导出excel&#xff0c;包括导出图片以及导出下拉框 1.最基本的导出excel 1.引入maven <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.1</version> </dependen…

MySQL复合查询解析

&#x1f388;行百里者半九十&#x1f388; &#x1f388;目录&#x1f388; 概念多表查询自连接子查询单行子查询多行子查询in关键字all关键字any关键字 多列子查询在from中使用子查询合并查询unionunion all 总结 概念 之前我们很多的查询都只是对于单表进行查询&#xff0c…

DMA技术在STM32中优化UART、SPI和I2C通信性能的研究与实现

DMA&#xff08;Direct Memory Access&#xff0c;直接存储器访问&#xff09;技术可以在STM32微控制器上优化UART、SPI和I2C等通信性能。DMA可以实现数据的高速传输&#xff0c;减轻CPU的负担&#xff0c;提高系统性能。在本篇文章中&#xff0c;我将探讨DMA技术在STM32中优化…

【C语言基础篇】结构控制(中)循环结构

文章目录 一、循环结构 1. while语句 2. for语句 3. do while语句 4. 循环结构总结 C语⾔是结构化的程序设计语⾔&#xff0c;这⾥的结构指的是顺序结构、选择结构、循环结构。也就是说在C语言所有的代码都是这三种结构。 本篇文章将会着重讲解循环结构 顺序结构和选…

数据结构图算法

算法就要多练,我在国庆节放假的时间编写了图的算法题,写完让我受益匪浅,希望可以帮助到大家. 文章目录 前言 一、图的数据结构 1.图的邻接表数据结构定义 2.图的邻接矩阵的存储形式 二、邻接表建立图代码 三、邻接表删除边(基本操作考试不考) 四、邻接表删除顶点及销毁整…

【MySQL进阶】索引

索引机制 索引介绍 MySQL 官方对索引的定义为&#xff1a;索引&#xff08;index&#xff09;是帮助 MySQL 高效获取数据的一种数据结构&#xff0c;**本质是排好序的快速查找数据结构。**在表数据之外&#xff0c;数据库系统还维护着满足特定查找算法的数据结构&#xff0c;这…

用el-image-viewer实现全局预览图片

背景 在后台管理系统中&#xff0c;一些预览图片的场景&#xff0c;通常都是使用 el-image-viewer 去实现&#xff0c;但是如果多个地方都需要预览图片&#xff0c;又要重复的去写 el-image-viewer 以及一些重复的和预览相关的代码。 可以把预览图片的组件放在根文件&#x…

洛谷P2615 [NOIP2015 提高组] 神奇的幻方(C语言)

这普及题太水了&#xff0c;你按照他给的条件来列判断语句。 按题目一步一步模拟 首先将1写在第一行的中间。 若K-1在第一行但不在最后一列&#xff0c;则将K填在最后一行&#xff0c;K-1所在列的右一列&#xff1b; 若K-1在最后一列但不在第一行&#xff0c;则将K填在第一…