vue实现日历控件
Vue 实现日历控件的方法
使用第三方库(如 FullCalendar)
安装 FullCalendar 及其 Vue 适配器:
npm install @fullcalendar/vue @fullcalendar/core @fullcalendar/daygrid
在 Vue 组件中引入并配置:
<template>
<FullCalendar :options="calendarOptions" />
</template>
<script>
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
export default {
components: { FullCalendar },
data() {
return {
calendarOptions: {
plugins: [dayGridPlugin],
initialView: 'dayGridMonth',
events: [
{ title: 'Meeting', start: new Date() }
]
}
}
}
}
</script>
自定义日历组件
创建基础的日历模板结构:
<template>
<div class="calendar">
<div class="header">
<button @click="prevMonth">←</button>
<h2>{{ currentMonth }}</h2>
<button @click="nextMonth">→</button>
</div>
<div class="days">
<div v-for="day in days" :key="day" class="day-header">{{ day }}</div>
</div>
<div class="dates">
<div
v-for="date in visibleDates"
:key="date.getTime()"
:class="{ 'other-month': !isCurrentMonth(date) }"
@click="selectDate(date)"
>
{{ date.getDate() }}
</div>
</div>
</div>
</template>
实现日历逻辑:
<script>
export default {
data() {
return {
currentDate: new Date(),
days: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
}
},
computed: {
currentMonth() {
return this.currentDate.toLocaleString('default', { month: 'long', year: 'numeric' })
},
visibleDates() {
const start = this.getMonthStart()
const end = this.getMonthEnd()
const dates = []
let date = new Date(start)
while (date <= end) {
dates.push(new Date(date))
date.setDate(date.getDate() + 1)
}
return dates
}
},
methods: {
getMonthStart() {
const date = new Date(this.currentDate)
date.setDate(1)
const day = date.getDay()
date.setDate(date.getDate() - day)
return date
},
getMonthEnd() {
const date = new Date(this.currentDate)
date.setMonth(date.getMonth() + 1)
date.setDate(0)
const day = date.getDay()
date.setDate(date.getDate() + (6 - day))
return date
},
isCurrentMonth(date) {
return date.getMonth() === this.currentDate.getMonth()
},
prevMonth() {
this.currentDate.setMonth(this.currentDate.getMonth() - 1)
this.currentDate = new Date(this.currentDate)
},
nextMonth() {
this.currentDate.setMonth(this.currentDate.getMonth() + 1)
this.currentDate = new Date(this.currentDate)
},
selectDate(date) {
this.$emit('date-selected', date)
}
}
}
</script>
添加基础样式:
.calendar {
width: 350px;
font-family: Arial;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
}
.days {
display: grid;
grid-template-columns: repeat(7, 1fr);
text-align: center;
}
.dates {
display: grid;
grid-template-columns: repeat(7, 1fr);
grid-gap: 5px;
}
.dates div {
padding: 10px;
text-align: center;
cursor: pointer;
}
.dates div:hover {
background-color: #eee;
}
.other-month {
color: #ccc;
}
功能扩展建议
添加事件管理功能,允许用户为特定日期添加事件:
data() {
return {
events: {}
}
},
methods: {
addEvent(date, event) {
const key = date.toDateString()
this.events[key] = this.events[key] || []
this.events[key].push(event)
this.$forceUpdate()
}
}
在模板中显示事件:
<template>
<div class="date-cell" @click="selectDate(date)">
{{ date.getDate() }}
<div v-for="(event, index) in events[date.toDateString()]" :key="index">
{{ event }}
</div>
</div>
</template>
实现日期范围选择功能:

data() {
return {
selectedStart: null,
selectedEnd: null
}
},
methods: {
selectDate(date) {
if (!this.selectedStart || this.selectedEnd) {
this.selectedStart = date
this.selectedEnd = null
} else {
this.selectedEnd = date
if (this.selectedEnd < this.selectedStart) {
[this.selectedStart, this.selectedEnd] = [this.selectedEnd, this.selectedStart]
}
this.$emit('range-selected', {
start: this.selectedStart,
end: this.selectedEnd
})
}
}
}






