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

image

<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>
posted @ 2022-11-08 09:35  Chaplink  阅读(451)  评论(0编辑  收藏  举报