vue使用FullCalendar插件实现日历会议预约功能
此案例是用FullCalendar插件做一个会议日程预约功能,此功能可查看自己的日程安排会议信息等......
·
目录
前言:此案例是用FullCalendar插件做一个会议日程预约功能,此功能可查看自己的日程安排会议信息等......
FullCalend
FullCalendar插件官网:FullCalendar - JavaScript Event Calendar
具体的配置内容可以参考:最新FullCalendar中文文档_Helloweba
- 效果图(月)
- 效果图(周)
- 效果图(日)
1. vue 项目使用npm安装插件
npm install --save @fullcalendar/vue @fullcalendar/core @fullcalendar/daygrid @fullcalendar/timegrid @fullcalendar/interaction npm install moment
2. vue 页面代码(直接复制粘贴可用)
<template>
<div class="app-container home">
<!-- 按钮部分-->
<div style="margin-bottom: 10px;">
<el-row>
<!-- 会议申请按钮-->
<el-button type="primary" round style="float: left;" @click="toMeetingClick()">申请会议</el-button>
<!-- 普通查询日期区域-->
<span style="margin-left: 20px;">
<span style="margin-right: 0px;">会议开始日期:</span>
<el-date-picker v-model="queryStartDate" type="date" placeholder="选择日期">
</el-date-picker>
<span style="margin-left: 10px;">
<el-button icon="el-icon-search" @click="quertStart()" circle></el-button>
</span>
</span>
<!-- 高级查询按钮-->
<el-button type="primary" round style="float: right;" @click="drawer = true">高级查询</el-button>
</el-row>
</div>
<!-- 日程部分-->
<div style="box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);padding: 10px;">
<FullCalendar :options="calendarOptions" ref="FullCalendar" />
<!-- 点击会议弹窗内容 -->
<div v-if="selectedEvent">
<el-dialog :close-on-click-modal="true" :visible="this.showDialog" @close="closeDialog()" title="日程详情">
<h3>{{ this.selectedEvent.title }}</h3>
<p>开始时间:{{ this.selectedEvent.start }}</p>
<p>结束时间:{{ this.selectedEvent.end }}</p>
<p>内容:{{ this.selectedEvent.context }}</p>
<p>职位:{{ this.selectedEvent.zw }}</p>
<p>性别:{{ this.selectedEvent.sex }}</p>
<p>年龄:{{ this.selectedEvent.age }}</p>
</el-dialog>
</div>
</div>
<!-- 抽屉框部分-->
<div>
<el-drawer title="查询条件" :visible.sync="drawer" :with-header="true">
<span>......</span>
</el-drawer>
</div>
</div>
</template>
<script>
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import timeGridPlugin from '@fullcalendar/timegrid'
import interactionPlugin from '@fullcalendar/interaction'
import moment from 'moment';
export default {
components: {
FullCalendar
},
name: "schedule",
data() {
return {
//普通查询时间
queryStartDate: null,
//日程弹窗开关
showDialog: false,
//日程弹窗内容
selectedEvent: null,
//抽屉窗开关
drawer: false,
//日程内容集合
meetingArr: [{
id: 1,
title: `会议:炎亚纶与汪东城`,
start: '2023-07-25' + 'T08:00:00',
end: '2023-07-25' + 'T10:10:00',
context: '自定义的内容',
age: 18,
sex: '男',
zw: '董事长',
},
{
id: 2,
title: `会议:蔡徐坤私生子`,
start: '2023-07-29' + ' 10:00:00',
end: '2023-07-29' + ' 12:00:00',
},
{
id: 3,
title: `会议:萧亚轩真的快乐吗?`,
start: '2023-07-10' + 'T10:00:00',
end: '2023-07-13' + 'T12:00:00',
},
{
id: 3,
title: `会议:蔡徐坤私生子1`,
start: '2023-07-29' + ' 10:00:00',
end: '2023-07-29' + ' 13:00:00',
},
{
id: 4,
title: `会议:研发讨论会`,
start: '2023-08-04' + ' 10:00:00',
end: '2023-08-04' + ' 13:00:00',
}
],
calendarOptions: {
// 加载的视图
plugins: [dayGridPlugin, timeGridPlugin, interactionPlugin],
// 视图类型 初始显示的视图 视图名称规则 比如dayGridPlugin去掉Plugin 加上Month或者Week或者Day
initialView: 'timeGridWeek',
// 语言选项 设置为中文后 部分文本会替换为中文 但是不全面
locale: 'zh-cn',
// 配置日历头部
// 按钮: prev为切换(上)下一月(/周/日) next today 跳转到今天
// 文本: title 年月(YYYY-MM)
// 按钮: dayGridMonth月 timeGridWeek周 timeGridDay日
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay',
},
// 设置各种按钮的文字 默认是英文的
buttonText: {
today: '今天',
month: '月',
week: '周',
day: '日',
list: '表'
},
// 初始就存在的事件【日程内容】
initialEvents: [],
// 是否可拖拽
editable: true,
// 是否可选择添加
selectable: true,
// 选择时触发函数
select: this.handleDateSelect,
// 点击事项触发函数
eventClick: this.handleEventClick,
// 移动事项或者拓展事项时间触发函数
eventsSet: this.handleEvents,
// 全天行 的文本显示内容
allDayText: '全天',
// 最小时间
slotMinTime: '00:00:00',
// 最大时间
slotMaxTime: '23:59:59',
// 是否可以进行(拖动、缩放)修改
//editable: false
},
};
},
methods: {
/* 普通查询方法*/
quertStart() {
let calendarApi = this.$refs.FullCalendar.getApi()
//非空
if (this.queryStartDate != null) {
// gotoDate方法是让当前视图跳转到指定日期的位置
calendarApi.gotoDate(this.queryStartDate)
} else {
//跳转到今日
calendarApi.today()
}
},
/* 获取指定日期范围的所有日程信息 */
toClick() {
// 获取 FullCalendar 实例
const calendar = this.$refs.FullCalendar.getApi();
// 定义搜索范围的起始和结束时间
const startDate = moment("2015-06-06");
const endDate = moment("2028-06-08");
// 获取日历中的所有事件
const events = calendar.getEvents();
// 根据范围条件筛选事件
const filteredEvents = events.filter(event => {
// 获取事件的开始时间和结束时间
const eventStart = moment(event.start);
const eventEnd = moment(event.end);
// 判断事件是否在范围内
return eventStart.isBetween(startDate, endDate, null, '[]') || eventEnd.isBetween(startDate,
endDate, null, '[]');
});
// 处理筛选出的事件
console.log(filteredEvents);
},
/* 点击会议弹窗具体内容*/
handleEventClick(info) {
// 获取点击的事件对象
const event = info.event;
// 更新选中的事件
this.selectedEvent = {
title: event.title,
start: moment(event.start).format('YYYY-MM-DD HH:mm'),
end: moment(event.end).format('YYYY-MM-DD HH:mm'),
zw: event.extendedProps.zw,
context: event.extendedProps.context,
age: event.extendedProps.age,
sex: event.extendedProps.sex
};
console.info(info)
console.info(this.selectedEvent)
//开启弹窗
this.showDialog = true
},
/* 关闭日程弹窗方法*/
closeDialog() {
this.showDialog = false
},
/* 申请会议按钮 */
toMeetingClick() {
//根据自己的业务进行处理...
}
},
created() {
//给日程记录初始化
this.calendarOptions.initialEvents = this.meetingArr
}
};
</script>
<style scoped lang="scss">
/* 修改抽屉样式 */
::v-deep .el-drawer__header {
background-color: rgb(245, 245, 245);
padding: 0px 20px;
height: 50px;
color: #000000;
margin-bottom: 0px;
//font-weight: bolder;
font-size: 18px;
}
/* ::v-deep .el-drawer {
background-color: #e3e3e3 !important
} */
.home {
blockquote {
padding: 10px 20px;
margin: 0 0 20px;
font-size: 17.5px;
border-left: 5px solid #eee;
}
hr {
margin-top: 20px;
margin-bottom: 20px;
border: 0;
border-top: 1px solid #eee;
}
.col-item {
margin-bottom: 20px;
}
ul {
padding: 0;
margin: 0;
}
font-family: "open sans",
"Helvetica Neue",
Helvetica,
Arial,
sans-serif;
font-size: 13px;
color: #676a6c;
overflow-x: hidden;
ul {
list-style-type: none;
}
h4 {
margin-top: 0px;
}
h2 {
margin-top: 10px;
font-size: 26px;
font-weight: 100;
}
p {
margin-top: 10px;
b {
font-weight: 700;
}
}
.update-log {
ol {
display: block;
list-style-type: decimal;
margin-block-start: 1em;
margin-block-end: 1em;
margin-inline-start: 0;
margin-inline-end: 0;
padding-inline-start: 40px;
}
}
}
</style>
3. vue FullCalendar的内置函数以及配置项
// 切换到下一月/周/日
this.$refs.FullCalendar.getApi().next()
// 切换到上一月/周/日
this.$refs.FullCalendar.getApi().prev()
// 跳转到今天
this.$refs.FullCalendar.getApi().today()
// 跳转到指定日期 formatData是日期 格式为 yyyy-MM-dd
// 特别注意不要写例如 2021-8-7 必须是 2021-08-07 两位!!!
this.$refs.FullCalendar.getApi().gotoDate(formatData)
// 获得当前视图起始位置的日期
this.$refs.FullCalendar.getApi().getDate()
// 获得当前视图 里面有一些参数
this.$refs.FullCalendar.getApi().view
// 当前视图的类型
this.$refs.FullCalendar.getApi().view.type
// 当前显示的事件(日程)的开始时
this.$refs.FullCalendar.getApi().view.activeStart
// 当前显示的事件(日程)的结束时
this.$refs.FullCalendar.getApi().view.activeEnd
// 这个应该是当前显示内容区域的日历引用 因为通过他可以获得内置的函数 (我也不确定 反正我是这么用的)
this.$refs.FullCalendar.getApi().view.calendar
// 获得当前所显示的所有事件(日程)
this.$refs.FullCalendar.getApi().view.calendar.getEvents()
// 向日历中添加事项
this.$refs.FullCalendar.getApi().view.calendar.addEvent({
id: 1,
title: `事项xx`,
start: '2021-10-01' + ' 13:00:00',
end: '2021-10-01' + ' 17:00:00',
// 修改背景颜色
backgroundColor:'#d8377a',
// 修改边框颜色
borderColor:'#d8377a',
})
- 获取指定日期范围的所有日程信息
// 获取 FullCalendar 实例
const calendar = this.$refs.FullCalendar.getApi();
// 定义搜索范围的起始和结束时间
const startDate = moment("2015-06-06");
const endDate = moment("2028-06-08");
// 获取日历中的所有事件
const events = calendar.getEvents();
// 根据范围条件筛选事件
const filteredEvents = events.filter(event => {
// 获取事件的开始时间和结束时间
const eventStart = moment(event.start);
const eventEnd = moment(event.end);
// 判断事件是否在范围内
return eventStart.isBetween(startDate, endDate, null, '[]') || eventEnd.isBetween(startDate,endDate, null, '[]');});
// 处理筛选出的事件
console.log(filteredEvents);
- 对于需要重新刷新当前显示日历中的事件(日程)时
// 是需要先清除 当前显示的各个eventSource(事件源) 就是事件(日程)
this.$refs.FullCalendar.getApi().view.calendar.getEvents().forEach(eventSource => {
eventSource.remove()
})
// 在将自己需要的内容加入
// 如果是只添加一个事件其他不动的话就不需要清除
- 其他一些基本的日历设置 (可参考里面的属性怎么设置使用第一版)
data() {
let that = this
return {
createEventId: 0,
calendarOptions: {
plugins: [dayGridPlugin,timeGridPlugin,interactionPlugin],
// 视图类型
initialView: 'timeGridWeek',
// 语言选项
locale:'zh-cn',
// 设置各种默认按钮的文字 没使用自定义按钮 并且 不需要在按钮添加自己的代码就直接用这个改一下显示文字就行
buttonText:{
today:'今天',
month:'月',
week:'周',
day:'日',
list:'表'
},
// 自定义头部按钮 因为要加一些自己的内容 自带的按钮未找到回调函数
customButtons:{
prevBack: {
text: '后退',
click: function(data) {
that.$refs.FullCalendar.getApi().prev()
// 自动一些内容
}
},
prevGo: {
text: '前进',
click: function(data) {
that.$refs.FullCalendar.getApi().next()
// 自动一些内容
}
},
ToToday: {
text: '今天',
click: function(data) {
that.$refs.FullCalendar.getApi().today()
// 自动一些内容
}
},
},
// 头部显示的功能 自定义按钮就显示在这
headerToolbar: {
left: 'prevBack,prevGo ToToday',
center: 'title',
right: 'dayGridMonth,timeGridWeek',
},
// 初始化的事件
initialEvents: [],
// 是否可拖拽
// editable: true,
// 是否可选择添加
// selectable: true,
selectMirror: true,
dayMaxEvents: true,
weekends: true,
// 选择时触发函数
select: this.handleDateSelect,
// 点击事件触发函数
eventClick: this.handleEventClick,
// 移动到事件上触发函数
eventMouseEnter:this.handleEventMouseover,
// 移动事件或者拓展事件时间触发函数
eventsSet: this.handleEvents,
// 全天行 的文本显示内容
allDayText: '全天',
// 是否显示全天
allDaySlot: true,
// 最小时间
slotMinTime:'06:00:00',
// 最大时间
slotMaxTime:'21:00:00',
},
}
},
- 其他一些基本的日历设置 (可参考里面的属性怎么设置使用第二版)
data() {
return {
calendarOptions: {
// 引入的插件
plugins: [dayGridPlugin, timeGridPlugin, interactionPlugin],
// 日历头部按钮位置
headerToolbar: {
left: "prev,next today",
center: "title",
right: "dayGridMonth, timeGridWeek, timeGridDay",
},
// 日历头部按钮中文转换
buttonText: {
today: "今天",
month: "月",
week: "周",
day: "天",
},
customButtons: {
prev: {
text: "上个月",
click: () => {
this.prev();
},
},
next: {
text: "下个月",
click: () => {
this.next();
},
},
today: {
text: "今天",
click: () => {
this.today();
},
},
},
locale: "zh-ch", // 切换语言,当前为中文
firstDay: "1", // 设置一周中显示的第一天是周几,周日是0,周一是1,以此类推
weekNumbers: true,
weekNumberCalculation: "ISO", // 与firstDay配套使用
weekNumberContent: this.weekNumberContent,
eventColor: "#3d8eec", // 全部日历日程背景色
timeGridEventMinHeight: "20", // 设置事件的最小高度
aspectRatio: "1.5", // 设置日历单元格宽高比
displayEventTime: true, // 是否显示事件时间
allDaySlot: false, // 周、日视图时,all-day不显示
allDayDefault: false,
editable: true, //是否允许修改事件
selectable: true,
eventLimit: true, // 设置月日程,与all-day slot 的最大显示数量,超过的通过弹窗展示
eventTimeFormat: {
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
hour12: false,
},
slotLabelFormat: {
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
meridiem: false,
hour12: false, // 设置时间为24小时制
},
events: [], // 日程数组
// 事件
editable: true, // 是否可以进行(拖动、缩放)修改
eventStartEditable: true, // Event日程开始时间可以改变,默认为true,若为false,则表示开始结束时间范围不能拉伸,只能拖拽
eventDurationEditable: true, // Event日程的开始结束时间距离是否可以改变,默认为true,若为false,则表示开始结束时间范围不能拉伸,只能拖拽
selectable: true, // 是否可以选中日历格
selectMirror: true,
selectMinDistance: 0, // 选中日历格的最小距离
weekends: true,
navLinks: true, // 天链接
selectHelper: false,
selectEventOverlap: false, // 相同时间段的多个日程视觉上是否允许重叠,默认为true,允许
dayMaxEvents: true,
dateClick: this.handleDateClick, // 日期点击
eventsSet: this.handleEvents, // 事件点击
eventClick: this.handleEventClick, // 日程点击信息展示
eventDrop: this.handleEventDrop, // 日程拖动事件
eventResize: this.eventResize, // 日程缩放事件
},
condition: [],
dialogShow: false,
rules: {
title: { required: true, message: "请填写标题", trigger: "blur" },
times: [
{ required: true, message: "请选择起始结束时间", trigger: "blur" },
],
task_type: { required: true, message: "请选择工段", trigger: "blur" },
},
BusinessModel: {
id: null,
title: null,
start_time: null,
end_time: null,
remark: null,
times: [],
task_type: null
},
dialogTitle : null,
productTaskType: {},
};
}
更多推荐
已为社区贡献2条内容
所有评论(0)