(基于vue)实现效果

文章目录

前言

一、FullCalendar是什么?

二、使用步骤

1.引入库

2.html部分代码

3.css样式代码(样式我单独写个scss文件引入的)

4.逻辑代码部分

总结


前言

闲来无事搞个排班排课表,之前貌似遇到过这类的需求,只不过没做上。主要用的就是FullCalendar插件。基于vue框架写法。

基本的功能可以新建个日程看看样式,可以拖拽日程进去。


提示:以下是本篇文章正文内容,下面案例可供参考

一、FullCalendar是什么?

Fullcalendar是一个非常受欢迎的日历日程处理的js组件,它功能强大,文档齐全,可定制化高,可与你的项目无缝对接。

官网链接:https://fullcalendar.io/demos

主要是针对于jq为基础写的插件,官网文档是全英文的,所以还要靠万能的度娘。

这里附个链接,在Vue框架下使用Fullcalendar_Helloweba

里面是详细讲解用vue写法的插件用法,只不过我原封照搬的时候遇到很多问题,后面我会总结一下。

二、使用步骤

1.引入库

代码如下(示例):

npm install @fullcalendar/core

npm install @fullcalendar/vue

npm install @fullcalendar/daygrid

npm install @fullcalendar/interaction

npm install @fullcalendar/timegrid

npm install @fullcalendar/list

(这个也可以一次npm install 由于我一次性安装出问题了我就一个一个安装的)

import '@fullcalendar/core'; // solves problem with Vite
import FullCalendar from '@fullcalendar/vue';
import dayGridPlugin from '@fullcalendar/daygrid';
import interactionPlugin,{ Draggable } from '@fullcalendar/interaction';
import timeGridPlugin from '@fullcalendar/timegrid';
import listPlugin from '@fullcalendar/list';
import moment from "moment";

2.html部分代码

这部分没啥说的,做的页面布局,我搞的都是纯静态的,有需要的直接复制粘贴就行,css样式我是用scss文件引入的,代码放在下面。

<template><div class="calendar"><div class="calendar_header"><el-input v-model="searchVal" placeholder="请输入内容"></el-input><el-button type="primary" @click="dialogAdd">+ 新建日程</el-button></div><div class="calendar_body"><div class="calendar_body_left"><div class="calendar_body_left_top"><div class="calendar_body_left_top_title">日程状态图例</div><div><el-button class="unstart_btn">未开始</el-button><el-button class="doing_btn">进行中</el-button><el-button class="success_btn">已完成</el-button><el-button class="delay_btn">已延时</el-button></div></div><div class="calendar_body_left_bottom"><div class="calendar_body_left_bottom_title">可拖动列表</div><div class="date-box" id="list-group-item"><div class="flex-b box list-group-item" v-for="item in list" :key="item.name"><div>{{ item.name }}</div><div class="circle" :class="item.status">{{ item.value }}</div></div></div></div></div><div class="calendar_body_right"><template><FullCalendar ref="fullCalendar" :options="calendarOptions" /></template></div></div><!-- 新建日程弹窗 --><el-dialog title="新建日程" :visible.sync="dialogFormVisible"><el-form :model="form" :rules="rules" ref="form"><el-form-item label="日程名称" :label-width="formLabelWidth"  prop="name"><el-input v-model="form.name" autocomplete="off"></el-input></el-form-item><el-form-item label="日程状态" :label-width="formLabelWidth" prop="status"><el-select v-model="form.status" placeholder="请选择日程状态"><el-option label="未开始" value="unstart"></el-option><el-option label="进行中" value="doing"></el-option><el-option label="已完成" value="success"></el-option><el-option label="已延时" value="delay"></el-option></el-select></el-form-item><el-form-item label="日程时间" :label-width="formLabelWidth"  prop="date"><template><el-date-pickerv-model="form.date"type="datetimerange"value-format="yyyy-MM-dd HH:mm:ss"range-separator="至"start-placeholder="开始日期"end-placeholder="结束日期"></el-date-picker></template></el-form-item></el-form><div slot="footer" class="dialog-footer"><el-button @click="dialogFormVisible = false">取 消</el-button><el-button type="primary" @click="submitForm('form')">确 定</el-button></div></el-dialog></div>
</template>

3.css样式代码(样式我单独写个scss文件引入的)

.calendar{padding: 0 20px;.el-button{width: 100px;}.calendar_header{display: flex;margin: 30px 0;.el-input{width: 200px;margin-right: 16px;}}  .calendar_body{display: flex;.calendar_body_left{display: flex;flex-direction: column;width: 10%;.el-button{margin-left: 0 !important;color: #fff;margin-bottom: 4px;}.unstart_btn{background-color: #ffcc99;}.doing_btn{background-color: #5580ee;}.success_btn{background-color: #87d068;}.delay_btn{background-color: #FF0033;}}.calendar_body_right{width: 85%;}}.el-dialog{width: 30%;}.el-date-editor.el-range-editor.el-input__inner.el-date-editor--datetimerange{width: 100%;}.el-select{width: 100%;}.calendar_body_left_top{.calendar_body_left_top_title{margin-bottom: 15px;font-size: 18px;font-weight: bolder;}}.calendar_body_left_bottom{padding: 0 25px;margin-top: 20px;.calendar_body_left_bottom_title{font-size: 18px;font-weight: bolder;}.circle {background-color: #3788d8;border-radius: 10px;color: #fff;display: inline-block;font-size: 12px;height: 18px;line-height: 18px;padding: 0 6px;text-align: center;white-space: nowrap;border: 1px solid #fff;}.holiday {background-color: #FF6600;}.work{background-color: #66CCCC;}.date-box {//border: 1px solid #ccc;border-radius: 5px;}.box {margin-top:15px;border: 1px solid #FFFFCC;padding: 10px 20px;border-radius: 5px;display: flex;justify-content: space-between;cursor: pointer;background-color: #FFFFCC;}}
}

4.逻辑代码部分

先上代码

<script>
// @ is an alias to /src
import "@/assets/css/calendar.scss"import '@fullcalendar/core'; // solves problem with Vite
import FullCalendar from '@fullcalendar/vue';
import dayGridPlugin from '@fullcalendar/daygrid';
import interactionPlugin,{ Draggable } from '@fullcalendar/interaction';
import timeGridPlugin from '@fullcalendar/timegrid';
import listPlugin from '@fullcalendar/list';
import moment from "moment";export default {name: 'Home',components: {FullCalendar},data() {return {n:4,searchVal:'',dialogFormVisible:false,formLabelWidth: '120px',form:{name: '',date: '',status:'',},rules: {name: [{ required: true, message: '请输入日程名称', trigger: 'blur' },// { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }],date: [{ required: true, message: '请选择日期', trigger: 'change' }],status: [{ required: true, message: '请选择日程状态', trigger: 'change' }]},testData:[{id: 1,title: '任务1未开始',start: '2023-04-06 10:30:00',end: '2023-04-07 10:30:00',// color: '#ffcc99',status:'unstart',editable: true, //允许拖动缩放,不写默认就是falseoverlap: true, //允许时间重叠,即可以与其他事件并存,不写默认就是false},{id: 2,title: '任务2进行中',start: '2023-04-06 10:30:00',end: '2023-04-08 10:30:00',// color: '#5580ee',status:'doing',editable: true, //允许拖动缩放overlap: true, //允许时间重叠,即可以与其他事件并存,不写默认就是false},{id: 3,title: '任务3已完成',start: '2023-04-09 10:30:00',end: '2023-04-09 18:30:00',// color: '#87d068',status:'success',editable: true, //允许拖动缩放overlap: true, //允许时间重叠,即可以与其他事件并存,不写默认就是false},{id: 4,title: '任务4已延时',start: '2023-04-18 10:30:00',end: '2023-04-18 10:30:00',// color: '#ff99b3',status:'delay',editable: true, //允许拖动缩放overlap: true, //允许时间重叠,即可以与其他事件并存,不写默认就是false}],// 可拖动列表数据list: [// { name: '删除假日', value: '0', color: 'blue'  }{ name: '工作日1', value: '1', status: 'work' },{ name: '工作日2', value: '5', status: 'work' },{ name: '春节放假', value: '7', status: 'holiday' },{ name: '中秋节放假', value: '3', status: 'holiday'  },{ name: '国庆节放假', value: '7', status: 'holiday'  },],calendarOptions: {plugins: [dayGridPlugin, timeGridPlugin, interactionPlugin, listPlugin],initialView: 'dayGridMonth',locale: 'zh-cn', //? 配置中文firstDay: 1,// 把每周设置为从周一开始initialDate: moment().format("YYYY-MM-DD HH:mm:ss"), // 自定义设置背景颜色时一定要初始化日期时间aspectRatio: 2.6, // 设置日历单元格宽度与高度的比例。buttonText: {/* 设置按钮文字 */today: '今天',month: '月',week: '周',day: '日',list: '周列表',},headerToolbar: {//日历头部left: 'prev,next today',center: 'title',right: 'dayGridMonth,timeGridWeek,timeGridDay listWeek',},selectable: true,//可编辑// dayMaxEvents: true,// slotMinutes: 15,editable: false, // 日历上是否可拖拽droppable: true,dropAccept: '.list-group-item',drop: this.drop,height: 650,validRange: this.validRange,  //设置可显示的总日期范围events: [], //背景色 (添加相同时间的背景色时颜色会重叠)datesSet: this.datesSet, //日期渲染;修改日期范围后触发eventClick: this.handleEventClick, //点击日程触发dateClick: this.handleDateClick, //点击日期触发eventDrop: this.calendarEventDropOrResize, //拖动事件触发eventResize: this.calendarEventDropOrResize, //缩放事件触发displayEventTime: false, //不显示具体时间},validRange: {start: '2023-01-01 ',end: moment().add(6, 'months').format('YYYY-MM-DD HH:mm:ss'),},new_startDate:'',new_endDate:'',}
},
mounted() {// 初始化日历 调用获取视图活动数据方法this.datesSet();// 拖拽var containerEl = document.getElementById('list-group-item');// 初始化外部事件new Draggable(containerEl, {itemSelector: '.list-group-item',})
},
methods: {datesSet(info) {   //注意:该方法在页面初始化时就会触发一次// console.log(info)// this.search()  //请求本页数据//虚拟数据this.testData.forEach((item,index) => {// console.log('item',item)if(item.status == 'unstart'){this.$set(item,"color", "#ffcc99")}else if(item.status == 'doing'){this.$set(item,"color", "#5580ee")}else if(item.status == 'success'){this.$set(item,"color", "#87d068")}else if(item.status == 'delay'){this.$set(item,"color", "#FF0033")}else if(item.status == 'work'){this.$set(item,"color", "#66CCCC")}else{this.$set(item,"color", "#FF6600")}});this.calendarOptions.events = this.testDatathis.list.forEach((item,index) => {if(item.status == 'work'){this.$set(item,"color","#66CCCC")}else{this.$set(item,"color","#FF6600")}})},dialogAdd(){this.dialogFormVisible = true},submitForm(formName) {this.$refs[formName].validate((valid) => {if (valid) {this.dialogFormVisible = false;this.n ++// console.log('date',this.form.date)let obj = {id: Number(this.n),title: String(this.form.name),start: String(this.form.date[0]),end: String(this.form.date[1]),// color: '#ff99b3',status:String(this.form.status),editable: true, //允许拖动缩放overlap: true, //允许时间重叠,即可以与其他事件并存,不写默认就是false}this.testData.push(obj)this.datesSet();// console.log('this.calendarOptions.events',this.calendarOptions.events)} else {console.log('error submit!!');return false;}});},// 转换时间格式parseTime(date) {const yy = date.getFullYear()const MM = (date.getMonth() + 1) < 10 ? '0' + (date.getMonth() + 1) : (date.getMonth() + 1)const dd = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()const HH = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()const mm = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()const ss = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()const   newDate = yy + '-' + MM + '-' + dd + ' ' + HH + ':' + mm + ':' + ss;return newDate;},handleEventClick(info) {},handleDateClick(info){},// 拖拽事件calendarEventDropOrResize(info){// console.log(info) //获取拖拽目标信息// 获取拖拽后的时间this.new_startDate = this.parseTime(info.event._instance.range.start)this.new_endDate = this.parseTime(info.event._instance.range.end)},drop(date, allDay) {// let typeNumber = null// const firstChildName = nullconst isWork = date.draggedEl.lastChild.className.indexOf('work') > 0console.log('date',date)date.draggedEl.remove()this.n ++const obj = {// dayNum: date.draggedEl.lastChild.innerHTML,id: Number(this.n),title: String(date.draggedEl.firstChild.innerHTML),start: Date.parse(moment(date.dateStr).format()), // 开始时间end: Date.parse(moment(date.dateStr).add(date.draggedEl.lastChild.innerHTML, 'days').format()), // 结束时间// color: '#ff99b3',status:isWork ? 'work' : 'holiday',editable: true, //允许拖动缩放overlap: true, //允许时间重叠,即可以与其他事件并存,不写默认就是false}this.testData.push(obj)this.datesSet();// console.log(this.calendarOptions.events)// console.log('date.draggedEl.lastChild.innerHTML',date.draggedEl.lastChild.className.indexOf('holiday'))}
}};
</script>

5.踩坑部分

以上代码直接cv应该就可以实现一个静态的日历排班表了。下面来说说我实现的过程遇到那些问题:

(1)这一块看别人写的都是 import '@fullcalendar/core/vdom' // solves problem with Vite

但是咱是vue2写的不适用。但是nodemodules包中有core文件我就把后面去掉了

(2)在安装的时候总是会出现以下报错

viewType "" is not available. Please make sure you've loaded all neccessary plugins

不要指定安装版本直接install就行。报错不行就全部uninstall,重新下载。package.json文件里面没了才是卸载完成。我遇到的问题就是一次性下载后报错,我没卸载,看别人的版本可以,我直接又下载了别人的版本,结果还是不行,一定卸载干净再重新下载。我觉得安装我上面的代码应该不会报错,前提是你的node版本什么的和我差不多哈哈

(3)这块这些Fullcalendar日历插件的事件的Info可以打印出当前拖拽的信息,比如拖拽前后的时间,还有样式什么的都可以在这里修改。打印出来附在下面啦        event就是拖拽后的信息,oldevent就是拖拽前的。我主要拿时间所以截图下面了。

 

(4)drop这块的拖拽主要是实现将左侧可拖拽列表中的日程拖放到Fullcalendar日历中。拖拽左侧日程块后打印date也可以获得好多有用的信息啦

 


总结

以上就是实现简易排班排课表的雏形啦,复杂的功能还是要基于数据啦,静态只是看看大概。先说这么多,后面有坑我再写;以及后面看看能不能再加上些好玩的功能。

FullCalendar 日历插件排班表排课表保姆级详解(可拖动排班排课)相关推荐

  1. fullcalendar php,php使用fullcalendar日历插件详解,fullcalendar日历

    php使用fullcalendar日历插件详解,fullcalendar日历 最近做课程表的项目,找了好多个插件感觉都不好用,无意间看到了fullcalendar,还挺简单的,很方便,先贴一张项目页面 ...

  2. fullcalendar日历插件的使用并实现增删改查

    我上个项目是做了一个关于教育方面的web端页面,其中的课程表就要用到fullcalendar日历插件,刚开始也是不会用,因为以前也没用过,后面也是看官方文档,问同事,最后完成了这个课程表,个人感觉fu ...

  3. fullcalendar日历插件的使用并动态增删改查

    我上个项目是做了一个关于教育方面的web端页面,其中的课程表就要用到fullcalendar日历插件,刚开始也是不会用,因为以前也没用过,后面也是看官方文档,问同事,最后完成了这个课程表,个人感觉fu ...

  4. fullcalendar日历插件的使用并动态增删改查(转载)

    我上个项目是做了一个关于教育方面的web端页面,其中的课程表就要用到fullcalendar日历插件,刚开始也是不会用,因为以前也没用过,后面也是看官方文档,问同事,最后完成了这个课程表,个人感觉fu ...

  5. FullCalendar 二:FullCalendar日历插件说明文档

    FullCalendar提供了丰富的属性设置和方法调用,开发者可以根据FullCalendar提供的API快速完成一个日历日程的开发,本文将FullCalendar的常用属性和方法.回调函数等整理成中 ...

  6. java显示日历 插件_JavaWeb项目FullCalendar日历插件使用的示例代码

    本文介绍了JavaWeb项目FullCalendar日历插件使用的示例代码,分享给大家,具体如下: 使用FullCalendar需要引用的文件 1.css文件 2.js文件 生成日历主界面 FullC ...

  7. Sep 15 FullCalendar日历插件说明文档

    Sep 15 FullCalendar日历插件说明文档 helloweba.com 作者:月光光 时间:2013-09-15 13:53 标签: FullCalendar  日历  文档 FullCa ...

  8. Oracle创建表语句(Create table)语法详解及示例

    Oracle创建表语句(Create table)语法详解及示例   创建表(Create table)语法详解 1. ORACLE常用的字段类型ORACLE常用的字段类型有 VARCHAR2 (si ...

  9. Java中常见RuntimeException与其他异常表及Exception逻辑关系详解

    Java中常见RuntimeException与其他异常表及Exception逻辑关系详解 前言 常见`RuntimeException` 其他错误类型 `Error`类 `Exception`类 E ...

最新文章

  1. 大数据遇上大型机 结果会如何?
  2. python里面ca_Python SSL服务器提供中间CA证书
  3. 基于ARM A53开发板,使用按键中断及中断底半部实现《led灯状态取反》的驱动
  4. 洛谷 P1340 兽径管理
  5. SQL进阶六:字符串函数
  6. Mysql JOIN连接算法
  7. luogu P2344 奶牛抗议 DP 树状数组 离散化
  8. 601. 体育馆的人流量
  9. 中级软件工程师的技能基本要求
  10. 基于访客的网络(VBN)
  11. springboot+mybatis打包时,单元测试类报错
  12. 数据分析 --- 如何分析数据
  13. 企业各职位英文缩写 PM,TM,PL,TL,SE,PG,CEO,CFO
  14. 织梦教程新建ID丨重置栏目ID丨文章ID不从1开始的解决方法
  15. 帮助计算机网络犯罪活动罪司法解释,帮助信息网络犯罪活动罪司法适用研究
  16. Python一键下载文章,转制成PDF格式电子书
  17. Cyclone V SoC FPGA学习之路第一章:综述
  18. 博图V14安装(无图流程)S7-1200
  19. BlackBerry 9850 大屏幕黑莓手机
  20. 网页设计经典色彩搭配

热门文章

  1. C语言编程求某人岁数
  2. 离任经济责任审计评议的主要内容
  3. leetcode-13-罗马数字转整数 Python 编程实现
  4. Pandas处理excel文件
  5. centos 关闭selinux 临时关闭selinux 报错 setenforce: setenforce() failed
  6. 解决docker中 pytz.exceptions.UnknownTimeZoneError: ‘Etc/UTC‘ 错误
  7. python one hot编码_One-Hot编码详解与Python实现
  8. SSM框架spring篇
  9. testng 无法注入service_头条锅边糊,连江人儿时与如今都无法忘怀的味道......
  10. FlashFXP等常用FTP软件如何设置二进制上传?