了解Vue中日历插件Fullcalendar

实现效果如下图:

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

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

官方文档地址: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>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

485.最大连续1的个数

前言 这两天突然发现力扣上还是有我能写出来的题的&#xff0c;虽说都是简单级别的&#xff08;以及一道中等的题&#xff09;&#xff0c;但是能写出来力扣真的太开心了&#xff0c;&#xff08;大佬把我这段话当个玩笑就行了&#xff09;&#xff0c;于是乎&#xff0c;我觉…

class_10:this关键字

this关键字是指向调用对象的指针 #include <iostream> #include <iostream> using namespace std;class Car{ public://成员数据string brand; //品牌int year; //年限//构造函数名与类名相同Car(string brand,int year){cout<<"构造函数中&#…

自学C语言-4

第4章 运算符与表达式 了解了程序中常用的数据类型后&#xff0c;还应该懂得如何操作这些数据。因此&#xff0c;掌握C语言中各种运算符与表达式是必不可少的。本章致力于使读者了解表达式的概念&#xff0c;掌握运算符及相关表达式的使用方法&#xff0c;其中包括赋值运算符、…

ChatGPT给出的前端面试考点(Vue.js)

ChatGPT给出的前端面试考点&#xff08;Vue.js&#xff09; 答案 1. Vue.js是什么&#xff1f;它的主要特点是什么&#xff1f; Vue.js是一个渐进式JavaScript框架&#xff0c;用于构建用户界面。它的主要特点包括&#xff1a; 数据绑定&#xff1a;Vue.js使用双向数据绑定&…

【2015~2024】大牛直播SDK演化史

大牛直播SDK的由来 大牛直播SDK始于2015年&#xff0c;最初我们只是想做个低延迟的RTMP推拉流解决方案&#xff0c;用于移动单兵等毫秒级延迟的场景下&#xff0c;我们先是实现了Android平台RTMP直播推送模块&#xff0c;当我们用市面上可以找到的RTMP播放器测试时延的时候&am…

C++深入之虚函数、虚继承与带虚函数的多基派生问题

基础 在讲解带虚函数的多基派生问题时&#xff0c;我们要先弄清楚不带虚函数的多基派生存在什么样的问题&#xff0c;这样才好弄明白带虚函数的多基派生问题。 多基派生的二义性问题 一般来说&#xff0c;在派生类中对基类成员的访问应当具有唯一性&#xff0c;但在多基继承…

国考省考行测:语句排序2刷题

国考省考行测&#xff1a;语句排序2刷题 2022找工作是学历、能力和运气的超强结合体! 公务员特招重点就是专业技能&#xff0c;附带行测和申论&#xff0c;而常规国考省考最重要的还是申论和行测&#xff0c;所以大家认真准备吧&#xff0c;我讲一起屡屡申论和行测的重要知识点…

RabbitMQ 部署与配置[CentOS7]

# RabbitMQ,Erlang 版本包对应 https://rabbitmq.com/which-erlang.html#eol-seriescd /usr/local/src# Erlang下载 # https://github.com/rabbitmq/erlang-rpm/releases https://github.com/rabbitmq/erlang-rpm/releases/download/v23.3.4.5/erlang-23.3.4.5-1.el7.x86_64.rp…

鸿蒙原生应用/元服务开发-延迟任务说明(一)

一、功能介绍 应用退至后台后&#xff0c;需要执行实时性要求不高的任务&#xff0c;例如有网络时不定期主动获取邮件等&#xff0c;可以使用延迟任务。当应用满足设定条件&#xff08;包括网络类型、充电类型、存储状态、电池状态、定时状态等&#xff09;时&#xff0c;将任务…

STM32G4芯片SPI1 CLK管脚AF Mode自动变化为0的问题

1 问题描述 最近在调试SPI Slave程序&#xff0c;遇到一个很奇怪的问题&#xff1a;单步调试时SPI1 CLK管脚AF Mode自动变化为0&#xff1b;但是在管脚初始化时&#xff0c;已经将其配置为5了。 2 问题现象 通过视频可见&#xff1a; STM32G4芯片SPI1 CLK管脚AF Mode自动变化…

写点东西《什么是网络抓取?》

写点东西《什么是网络抓取&#xff1f;》 什么是网络抓取&#xff1f; 网络抓取合法吗&#xff1f; 什么是网络爬虫&#xff0c;它是如何工作的&#xff1f; 网络爬虫示例 网络抓取工具 结论 您是否曾经想同时比较多个网站上同一件商品的价格&#xff1f;或者自动提取您最喜欢的…

win系统环境搭建(十四)——Windows系统下使用docker安装mysql8和mysql5.7

windows环境搭建专栏&#x1f517;点击跳转 win系统环境搭建&#xff08;十四&#xff09;——Windows系统下使用docker安装mysql8和mysql5.7 文章目录 win系统环境搭建&#xff08;十四&#xff09;——Windows系统下使用docker安装mysql8和mysql5.7MySQL81.新建文件夹2.创建…

实战之-Redis商户查询缓存

一、什么是缓存? 前言:什么是缓存? 就像自行车,越野车的避震器 举个例子:越野车,山地自行车,都拥有"避震器",防止车体加速后因惯性,在酷似"U"字母的地形上飞跃,硬着陆导致的损害,像个弹簧一样; 同样,实际开发中,系统也需要"避震器",防止过高…

Docker-nacos集群部署

nacos单机模式 先拉取一个mysql docker pull mysql:5.7 定义一个挂载目录 mkdir -p /mysql/{conf,data,script} 配置一个my.cnf放到conf目录下 开启mysql容器 privilegedtrue:使用该参数&#xff0c;container内的root拥有真正的root权限&#xff0c;否则&#xff0c;cont…

48-DOM节点,innerHTML,innerText,outerHTML,outerText,静态获取,单机click,cssText

1.DOM基础 Document Object Module,文档对象模型,window对象,document文档,都可以获取和操作 1)文档节点 2)属性节点(标签内的属性href,src) 3)文本节点(标签内的文字) 4)注释节点 5)元素节点(标签) 2.获取元素节点 2.1通过标签名获取getElementsByTagName() …

LeetCode、374. 猜数字大小【简单,二分】

文章目录 前言LeetCode、374. 猜数字大小【简单&#xff0c;二分】题目及类型思路及代码实现 资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝2W&#xff0c;csdn博客专家、Java领域优质创作者&#xff0c;博客之星、阿里云平台优质作者、专注于Java后端技术领域。 涵盖技…

RabbitMQ安装和使用

简介 RabbitMQ是一套开源&#xff08;MPL&#xff09;的消息队列服务软件&#xff0c;是由LShift提供的一个Advanced Message Queuing Protocol (AMQP) 的开源实现&#xff0c;由以高性能、健壮以及可伸缩性出名的Erlang写成。所有主要的编程语言均有与代理接口通讯的客户端库…

Ubuntu使用QtCreator + CMake 开发C/C++程序

平台 OS: Ubuntu 20.04 cmake: 3.16.3 IDE: Qt Creator 4.11.1 Based on Qt 5.14.1 (GCC 5.3.1 20160406 (Red Hat 5.3.1-6), 64 bit) Built on Feb 5 2020 12:48:30 From revision b2ddeacfb5 Copyright 2008-2019 The Qt Company Ltd. All rights reserved. The program …

【算法】斐波那契数列 [递推,矩阵快速幂]

方法一. 递推 class Solution { public:int fib(int n) {int MOD 1e9 7;if (n < 2) return n;int p 0, q 0, r 1;for (int i 2; i < n; i) {p q;q r;r (p q) % MOD;}return r;} }; 方法二&#xff1a;矩阵快速幂 class Solution { public:const int MOD 1e…

【Docker】Nacos的单机部署及集群部署

一、Nacos的介绍 Nacos是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。 动态服务发现&#xff1a;Nacos支持DNS与RPC服务发现&#xff0c;提供原生SDK、OpenAPI等多种服务注册方式和DNS、HTTP与API等多种服务发现方式。服务健康监测&#xff1a;Nacos提供…