首先吐槽这个Fullcalendar这个插件的沙雕文档,都是英文,谷歌翻译又翻译得很笨,查看了很多文档和博客,很都是复制粘贴党.浪费大家时间.
/***/在项目中需要加一个预约功能,后端传给我一个类似下图这样的数据结构,这个就是限制预约时间段,比如data数组中第一项data[0] = [15] 意思是周日 只有15点到16点可以预约.data[1]=[6,“8,12”] 就是周一的6点到7点,8点到下午三点可以预约,如图
1.首先需要下载Fullcalendar以及相关配置
npm install @fullcalendar/core @fullcalendar/daygrid @fullcalendar/timegrid @fullcalendar/moment @fullcalendar/interaction
这个是相关配置代码,其中比较关键的是有个点击事件和select事件重复,最后我选择了select事件,因为这个事件可以被限制范围,
下面列一些花很大精力查到的,用处很大的属性
columnHeaderFormat="ddd" // 格式化表头,成周一周二...默认为11/19周二,11/20周三...
:first-day="nowDay" //此处创建一个nowDay方法使当前日期始终在第一列,后面则为当前时期后六天
:business-hours="businessHours" //此处创建一个businessHours数组数据结构类似于[{
startTime:"6:00",endTime:"8:00",daysOfWeek:[0]}] ,daysOfWeek:[0]表示周日,daysOfWeek:[1]表示周一以此类推
:select-allow="handlerAllow" //此处设置一个handlerAllow方法限制select拉取的范围
min-time="00:00:00" max-time="24:00:00" slot-duration="01:00:00" //此处设置每天时间从什么时候开始结束,以及每段时间的间隔为多少
:eventConstraint="businessHours" //当事件拖动时,限制拖动到灰色区域
aspectRatio="1.5" //设置日历的宽高比率 ,发现有超出部分可以适当调整
:editable="true" :eventDurationEditable="false" //事件可以被拖动,禁止事件下拉(因为项目需要固定只能预约一个小时,下拉会导致时间增加)
:selectConstraint="businessHours" //这个属性找了两天,贼鸡儿难受,此处限制灰色区域创建预约,就是灰色部分不能被点击,eventConstraint这个只是事件拖动时不会被拖到灰色区域
:event-overlap="false" //阻止两次预约拖动时重叠
<template>
<div>
<div class="calendar">
<FullCalendar :plugins="calendarPlugins" :all-day-slot="false" :header="{ // 头部样式
left: 'today',
right:'next'
}" :button-text="{ //头部按钮样式
today: '今天'
}" :event-overlap="false" :events="event" columnHeaderFormat="ddd" :select-overlap="false"
:first-day="nowDay" :business-hours="businessHours" :select-allow="handlerAllow" :select-mirror="true"
selectable="true" min-time="00:00:00" max-time="24:00:00" slot-duration="01:00:00"
slot-label-format="HH:mm" default-view="timeGridWeek" locale="zh-cn" @eventClick="handleEventClick"
@eventDrop="handDrop" :eventConstraint="businessHours" @select="handleSelect" aspectRatio="1.5"
:editable="true" :eventDurationEditable="false" :resourceIds="businessHours"
:selectConstraint="businessHours" :valid-range="visibleRange" />
</div>
</div>
</template>
<script>
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin from '@fullcalendar/interaction'
import momentPlugin from '@fullcalendar/moment'
import '@fullcalendar/core/locales/zh-cn'
import timeGridPlulgin from '@fullcalendar/timegrid'
export default {
components: {
FullCalendar
},
data () {
return {
calendarPlugins: [dayGridPlugin, timeGridPlulgin, momentPlugin, interactionPlugin],
event: [
// {
// start: '2019-11-20 14:00:00',
// end: '2019-11-20 15:00:00',
// },
// {
// start: '2019-11-22 12:00:00',
// end: '2019-11-22 13:00:00'
// }
],
data: [
[15], //周日 0
[6, "8,12"], //周一 1
["10,17", 20], //周二 2
[], //周三 3
["9,15"],//周四 4
[],//周五 5
["15,24"],//周六 6
],
arr: [],
businessHours: []
}
},
computed: {
nowDay () {
//使得日历是当前时间的后七天
return new Date().getDay()
},
visibleRange () {
//限制日期时间,因为是预约功能,需要设置当前时间之后的多少天内可以预约,超过时间则不能预约
let nowDate = new Date()
return {
start: nowDate,
end: this.getDateStr(this.day) //后面写了一个方法转化
}
},
},
created () {
this.init()
},
methods: {
startFormatTime (t) {
let a = new Date(t).toJSON()
let b = new Date(+new Date(a) + 8 * 3600 * 1000)
let c = b.toISOString()
let d = c.replace(/T/g, ' ').replace(/\.[\d]{
3}Z/, '');
return d
},
getDateStr (t) {
var dd = new Date();
dd.setDate(dd.getDate() + t);
var y = dd.getFullYear();
var m = (dd.getMonth() + 1) < 10 ? "0" + (dd.getMonth() + 1) : (dd.getMonth() + 1);//获取当前月份的日期,不足10补0
var d = dd.getDate() < 10 ? "0" + dd.getDate() : dd.getDate();//获取当前几号,不足10补0
return y + "-" + m + "-" + d;
},
transform (val, k) {
if (typeof (val) == 'string') {
let a = val.split(",")
let b = {
startTime: `${
a[0]}:00`,
endTime: `${
a[1]}:00`,
daysOfWeek: [k]
}
this.arr.push(b)
} else if (typeof (val) == 'number') {
let c = {
startTime: `${
val}:00`,
endTime: `${
val + 1}:00`,
daysOfWeek: [k]
}
this.arr.push(c)
}
this.businessHours = this.arr
},
init () {
this.data.map((item, index) => {
item.map(j => {
this.transform(j, index)
})
})
},
handlerAllow: info => {
//这个是限制过去时间不能点击,并且限制每次点击只能预约一个小时,不能水平拉动
let a = info.start.getHours()
let b = info.end.getHours()
let c = info.start.getDay()
let d = info.end.getDay()
const currentDate = new Date()
const start = info.start
const end = info.end
return (start <= end && start >= currentDate && b - a == 1 && c == d)
},
handleSelect (info) {
this.$confirm('是否选择该时间为预约时间?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let a = {
start: this.startFormatTime(info.startStr),
end: this.startFormatTime(info.endStr),
}
if (this.event.length < 5) {
this.event = this.event.concat(a)
this.$message({
type: 'success',
message: '操作成功!'
});
} else {
this.$message({
type: 'warning',
message: '一周最多只能预约3次!'
});
}
}).catch(() => {
});
},
handleEventClick (val) {
console.log(1111, val)
},
handDrop (val) {
console.log(1, val)
}
}
}
</script>
<style lang="scss" scoped>
@import '~@fullcalendar/core/main.css';
@import '~@fullcalendar/daygrid/main.css';
@import '~@fullcalendar/timegrid/main.css';
</style>
其他部分没什么好说的,自己瞅吧,这沙雕插件就是属性难搞,找了好几天.希望大家以后发点干货,别瞎鸡儿转载转载,搜了都是一堆一模一样的东西