vue fullcalendar月周日历
参考
https://fullcalendar.io/demos
https://www.cnblogs.com/czk1634798848/p/13386178.html
https://blog.csdn.net/qq_39863107/article/details/105387879
引入了Day.js
npm install --save @fullcalendar/vue
下面包是日历的周视图、日视图等插件包:
npm install --save @fullcalendar/core @fullcalendar/daygrid @fullcalendar/interaction @fullcalendar/list @fullcalendar/timegrid
npm install dayjs --save
<template>
<div class='demo-app'>
<div class="calendar-header">
<!-- 切换周月视图按钮 -->
<el-radio-group v-model="radio1" size="mini" fill="#0C64EB" text-color="#fff">
<el-radio-button label="0">月</el-radio-button>
<el-radio-button label="1">周</el-radio-button>
<el-radio-button label="2">日</el-radio-button>
</el-radio-group>
<!-- 日期选择器 -->
<div class="date-box">
<el-date-picker
v-if="radio1 == '0'"
v-model="weekandmonth"
type="month"
format="yyyy 年 MM 月"
class="dper"
:clearable=false
:editable=false
@change="onchange"
placeholder="选择月">
</el-date-picker>
<el-date-picker
class="ppp"
v-else-if="radio1 == '1'"
v-model="weekandmonth"
type="week"
:clearable=false
format="yyyy 第 WW 周"
value-format="yyyy-MM-dd"
ref="weekRef"
:editable=false
@change="weekChange"
placeholder="选择周">
</el-date-picker>
<el-date-picker
v-else
v-model="weekandmonth"
type="date"
format="yyyy 年 MM 月 dd 日"
:clearable=false
:editable=false
@change="dayChange"
placeholder="选择日期">
</el-date-picker>
</div>
<div style="min-width:133px"></div>
</div>
<FullCalendar
class='demo-app-calendar'
ref="myCalendar"
:options='calendarOptions'
>
</FullCalendar>
<Details v-if="visible" :visible.sync="visible" :isEdit="isEdit" :checkItem="checkItem" @confirm="confirmFn"></Details>
</div>
</template>
<script src="js/plugins/fullcalendar/zh-cn.js"></script>
<script>
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import timeGridPlugin from '@fullcalendar/timegrid'
import interactionPlugin from '@fullcalendar/interaction'
import dayjs from 'dayjs'
import Details from './details.vue'
export default {
components: {
FullCalendar, // make the <FullCalendar> tag available
Details
},
data() {
return {
visible:false,
isEdit:false,
radio1: '0',
weekandmonth: new Date(),
calendarApi: null,
checkItem:{},
calendarOptions: {
// buttonText: {
// today: '今天',
// month: '月',
// week: '周',
// day: '日'
// },
allDayText:'全天',
slotLabelFormat: {
hour: '2-digit',
minute: '2-digit',
meridiem: false,
hour12: false // 设置时间为24小时
},
displayEventTime: false, // 是否显示时间
// allDaySlot: false, // 周,日视图时,all-day 不显示
firstDay: 0, // 设置一周中显示的第一天是哪天,周日是0,周一是1,类推
locale:'zh-cn',
plugins: [
dayGridPlugin,
timeGridPlugin,
interactionPlugin // needed for dateClick
],
headerToolbar: {
left: '',
center: '',
right: ''
},
initialView: 'dayGridMonth',
// initialEvents: [], // alternatively, use the `events` setting to fetch from a feed
events:[],
editable: false,
selectable: true,
selectMirror: true,
dayMaxEvents: true,
weekends: true,
select: this.handleDateSelect,
eventClick: this.handleEventClick,
eventsSet: this.handleEvents,
// eventMouseEnter: this.eventMouseEnter, // 鼠标滑过
/* you can update a remote database when these fire:
eventAdd:
eventChange:
eventRemove:
*/
},
currentEvents: []
}
},
created(){
this.getWeekTask('month',dayjs().format('YYYY-MM'))
},
mounted() {
this.calendarApi = this.$refs.myCalendar.getApi()
},
watch: {
weekandmonth(n, o) {
let d = dayjs(n).format('YYYY-MM-DD')
console.log(n)
this.calendarApi.gotoDate(d)
},
// 跳转日期
// month1(n, o) {
// console.log(new Date(n).format('YYYY-MM'))
// let d = new Date(n).format('YYYY-MM')
// this.calendarApi.gotoDate(d)
// },
radio1(n, o) {
// 切换月视图
if (n == '0') {
this.getWeekTask('month',dayjs(this.weekandmonth).format('YYYY-MM'))
this.calendarApi.changeView('dayGridMonth')
} else if (n == '1'){
// 切换周视图
this.getWeekTask('week',dayjs(this.weekandmonth).startOf('week').format('YYYY-MM-DD')+','+dayjs(this.weekandmonth).endOf('week').format('YYYY-MM-DD'))
this.calendarApi.changeView('timeGridWeek')
}else{
this.getWeekTask('day',dayjs(this.weekandmonth).format('YYYY-MM-DD'))
this.calendarApi.changeView('timeGridDay')
}
},
},
methods: {
// 截取周月
getYearWeek(v) {
let s = v.replace(/\D/g, '')
let y = s.slice(0, 4)
let w = s.slice(4)
return {
y,
w
}
},
onchange(val) {
console.log(val)
this.getWeekTask('month',val)
},
weekChange(val) {
let s = dayjs(val).startOf('week').format('YYYY-MM-DD')
let e = dayjs(val).endOf('week').format('YYYY-MM-DD')
this.getWeekTask('week',s+','+e)
},
dayChange(val){
this.getWeekTask('day',val)
},
// 获取周任务列表
async getWeekTask(type,val) {
let res = await this.$api.后端接口('参数')
this.calendarOptions.events = res.statue == 200?res.info:[]
console.log(this.calendarOptions.events)
// this.$forceUpdate();
},
handleDateSelect(selectInfo) { //展示弹窗
this.checkItem = {
id:'',
title:'',
loc:'',
notes:'',
ad:selectInfo.allDay,
iscycle:'0',
date:[]
}
if(selectInfo.allDay){
this.checkItem.date=[dayjs(selectInfo.start).format('YYYY-MM-DD 00:00:00'),dayjs(selectInfo.end).subtract(1, 'day').format('YYYY-MM-DD 23:59:59')]
}else{
this.checkItem.date=[selectInfo.start,selectInfo.end]
}
console.log(this.checkItem.date)
this.isEdit = false
this.visible = true
},
async handleEventClick(clickInfo) {
console.log(clickInfo.event);
let res = await this.$api.FindScheduleInfo({id:clickInfo.event.id})
if(res.statue==200){
this.checkItem = res.info
// this.checkItem.date=[res.info.start,res.info.end]
this.checkItem.ad = res.info.ad == '0'?false:true
this.$set(this.checkItem, 'date', [res.info.start,res.info.end])
}
this.isEdit = true
this.visible = true
},
handleEvents(events) {
this.currentEvents = events
},
async confirmFn(){
if (this.radio1 == '0') {
this.getWeekTask('month',dayjs(this.weekandmonth).format('YYYY-MM'))
} else if (this.radio1 == '1'){
// 切换周视图
this.getWeekTask('week',dayjs(this.weekandmonth).startOf('week').format('YYYY-MM-DD')+','+dayjs(this.weekandmonth).endOf('week').format('YYYY-MM-DD'))
}else{
this.getWeekTask('day',dayjs(this.weekandmonth).format('YYYY-MM-DD'))
}
this.visible = false
}
}
}
</script>
<style lang='scss' scoped>
/deep/ .el-dialog__wrapper{
z-index: 10000 !important;
}
/deep/ .el-input__icon{
line-height: 28px;
}
/deep/ .el-input__inner{
height: 28px;
line-height: 28px;
text-align: center;
}
.calendar-header {
display: flex;
height: 44px;
justify-content: space-between;
align-items: center;
// margin-bottom: 16px;
// background: pink;
// border-bottom: 1px solid #e8e8e8;
/deep/ .el-radio-button__inner {
// border: 1px solid #0c64eb;
color: #333;
}
.date-box {
position: relative;
display: flex;
justify-content: center;
align-items: center;
width: 200px;
// background: yellow;
// position: relative;
.el-icon-caret-bottom {
position: absolute;
top: 50%;
transform: translateY(-50%);
right: 3px;
}
}
}
/deep/ .fc .fc-toolbar-title{
display: inline-block;
font-size: 18px;
margin:0px 10px;
}
/deep/ .el-date-editor .el-range__icon{
line-height: 24px;
}
/deep/ .el-date-editor .el-range__close-icon{
line-height: 24px;
}
/deep/ .el-range-separator{
line-height: 24px;
}
/deep/ .fc .fc-button-primary{
background: #fff;
border: none;
color: #999;
outline: none;
}
/deep/ a{
color: #666;
}
/deep/ .fc .fc-toolbar.fc-header-toolbar{
margin-bottom:0
}
.demo-app {
display: flex;
flex-direction:column;
// margin: 10px;
// min-height: 100%;
height: calc(100% - 25px);
font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
font-size: 14px;
}
.demo-app-calendar{
width: 100%;
height: calc(100% - 60px);
// height: 100%;
}
</style>