Vue 实现日历日程表效果
使用到的组件
"@fullcalendar/core": "^4.3.1",
"@fullcalendar/daygrid": "^4.3.0",
"@fullcalendar/interaction": "^4.3.0",
"@fullcalendar/timegrid": "^4.3.0",
"@fullcalendar/vue": "^4.3.1",
组件代码
/**
* @Author: 858834013@qq.com
* @Name: workingCalendar
* @Date: 2022-07-19
* @Desc: 工作日历
*/
<template>
<div class="importantDocuments">
<div class="title">工作日历</div>
<div class="newsList">
<div class="newsLists">
<FullCalendar
ref="fullCalendar"
defaultView="dayGridMonth"
locale="zh-cn"
:header="{
left: 'prev,next',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
}"
:buttonText="buttonText"
:plugins="calendarPlugins"
:weekends="calendarWeekends"
:events="getCalendarEvents"
:eventLimit="true"
eventLimitText="更多"
@dateClick="handleDateClick"
@eventClick="handleEventClick"
/>
</div>
<div class="infoBody">
<div class="infoBodyItem">
<div class="dian1"></div>
<span>重要会议</span>
</div>
<div class="infoBodyItem">
<div class="dian2"></div>
<span>中心会议</span>
</div>
<div class="infoBodyItem">
<div class="dian3"></div>
<span>工作计划</span>
</div>
<div class="infoBodyItem">
<div class="dian4"></div>
<span>项目管控</span>
</div>
</div>
</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 '@fullcalendar/core/main.css'
import '@fullcalendar/daygrid/main.css'
import '@fullcalendar/timegrid/main.css'
export default {
name: "fullcalendars",
components: {
FullCalendar
},
props: {
id: {
type: String,
default() {
return '';
}
}
},
data() {
return {
buttonText: {
today: '今',
month: '月',
week: '周',
day: '天',
list: '列表'
},
calendarPlugins: [ // plugins must be defined in the JS
dayGridPlugin,
timeGridPlugin,
interactionPlugin // needed for dateClick
],
calendarWeekends: true,
calendarEvents: [ // initial event data
{
title: 'Event Now',
start: new Date(),
color: '#A61000'
}
],
calendarApi: null
}
},
watch: {},
mounted() {
this.calendarApi = this.$refs.fullCalendar.getApi()
},
methods: {
getCalendarEvents(info, successCallback, failureCallback) {
const events = [
...this.calendarEvents,
{
title: info.startStr,
start: info.start.valueOf()
}
]
successCallback(events)
},
toggleWeekends() {
this.calendarWeekends = !this.calendarWeekends // update a property
},
gotoPast() {
this.calendarApi.gotoDate('2019-08-01') // call a method on the Calendar object
},
handleDateClick(arg) {
if (confirm('Would you like to add an event to ' + arg.dateStr + ' ?')) {
this.calendarEvents.push({ // add new event data
title: 'New Event',
start: arg.date,
allDay: arg.allDay
})
}
this.calendarApi.refetchEvents()
},
handleEventClick(info) {
alert('Event: ' + info.event.title)
}
}
}
</script>
<style lang="scss" scoped>
.importantDocuments {
width: 100%;
height: 493px;
background: #FFFFFF;
border-radius: 20px;
.title {
font-size: 18px;
font-family: MicrosoftYaHei;
font-weight: bold;
color: #333333;
height: 55px;
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
padding-left: 20px;
}
.newsList {
width: 100%;
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-wrap: wrap;
flex-direction: row;
align-content: flex-start;
padding-left: 20px;
padding-right: 20px;
height: 380px;
position: relative;
}
.newsLists {
//height: 390px;
overflow: hidden;
}
}
.newsList {
::v-deep {
.fc-left {
position: absolute;
right: 20px;
top: 0px;
}
.fc-scroller {
//height: 280px !important;
}
.fc-body {
margin-top: 10px;
}
.fc th, .fc td {
border: none;
}
.fc-day-header {
font-size: 14px;
font-family: MicrosoftYaHei;
font-weight: 400;
color: #999F9E;
}
.fc-dayGrid-view .fc-body .fc-row {
min-height: 55px;
height: 55px !important;
}
.fc-day-grid-event {
width: 8px;
height: 8px;
background: #4E9AC1;
border-radius: 50%;
font-size: 0;
margin: 0 auto;
flex-shrink: 0;
padding: 0;
margin-top: 8px;
}
.fc-content {
}
.fc-day-number {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
float: none;
width: 100%;
//height: 34px;
font-size: 18px;
font-family: DIN;
font-weight: bold;
color: #343449;
border-radius: 50%;
}
td {
border: none;
}
.fc-center {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
}
.fc-toolbar h2 {
font-size: 18px;
font-family: MicrosoftYaHei;
font-weight: bold;
color: #4E9AC1;
}
.fc-button-primary:hover {
outline: none;
}
.fc-button-primary {
width: 40px;
height: 26px;
border: none;
background: #f8fafb;
border-radius: 0px;
outline: none;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
font-size: 14px;
font-family: MicrosoftYaHei;
font-weight: 400;
color: #859691;
}
.fc-button-active {
background: #4e9ac1;
color: #fff;
}
.fc-right {
margin-top: -80px;
position: absolute;
right: 20px;
}
.fc-left {
.fc-button-primary {
background: none;
}
}
}
}
.infoBody {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
width: 100%;
height: 50px;
margin-top: -50px;
.infoBodyItem {
width: 20%;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
font-size: 14px;
font-family: MicrosoftYaHei;
font-weight: 400;
color: #333333;
.dian1 {
width: 8px;
height: 8px;
background: #F84A5E;
border-radius: 50%;
margin-right: 8px;
}
.dian2 {
width: 8px;
height: 8px;
background: #1890ff;
border-radius: 50%;
margin-right: 8px;
}
.dian3 {
width: 8px;
height: 8px;
background: #4e9ac1;
border-radius: 50%;
margin-right: 8px;
}
.dian4 {
width: 8px;
height: 8px;
background: #f08d2b;
border-radius: 50%;
margin-right: 8px;
}
}
}
</style>