vue实现日历效果
Vue实现日历效果的方法
使用第三方库
Vue-Cal是一个专为Vue设计的日历组件库,支持月视图、周视图和日视图,具备事件拖拽、自定义样式等功能。安装方式:
npm install vue-cal
在组件中使用:

<template>
<vue-cal :events="events" />
</template>
<script>
import VueCal from 'vue-cal'
import 'vue-cal/dist/vue-cal.css'
export default {
components: { VueCal },
data() {
return {
events: [
{ start: '2023-10-01 10:00', end: '2023-10-01 12:00', title: '会议' }
]
}
}
}
</script>
手动实现基础日历
创建一个显示当月日期的网格布局,计算当月天数及起始星期:

<template>
<div class="calendar">
<div class="header">{{ currentMonth }}</div>
<div class="weekdays">
<div v-for="day in weekdays" :key="day">{{ day }}</div>
</div>
<div class="days">
<div
v-for="(date, index) in visibleDates"
:key="index"
:class="{ 'other-month': !date.isCurrentMonth }">
{{ date.day }}
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
currentDate: new Date(),
weekdays: ['日', '一', '二', '三', '四', '五', '六']
}
},
computed: {
currentMonth() {
return this.currentDate.toLocaleString('default', {
month: 'long',
year: 'numeric'
})
},
visibleDates() {
const year = this.currentDate.getFullYear()
const month = this.currentDate.getMonth()
const firstDay = new Date(year, month, 1)
const lastDay = new Date(year, month + 1, 0)
const startDay = firstDay.getDay()
const daysInMonth = lastDay.getDate()
const prevMonthDays = new Date(year, month, 0).getDate()
const dates = []
for (let i = startDay - 1; i >= 0; i--) {
dates.push({
day: prevMonthDays - i,
isCurrentMonth: false
})
}
for (let i = 1; i <= daysInMonth; i++) {
dates.push({
day: i,
isCurrentMonth: true
})
}
const remaining = 42 - dates.length
for (let i = 1; i <= remaining; i++) {
dates.push({
day: i,
isCurrentMonth: false
})
}
return dates
}
}
}
</script>
<style>
.calendar {
display: grid;
grid-template-rows: auto auto 1fr;
}
.weekdays, .days {
display: grid;
grid-template-columns: repeat(7, 1fr);
}
.other-month {
opacity: 0.5;
}
</style>
增强功能实现
添加月份切换和日期选择功能:
<script>
export default {
methods: {
prevMonth() {
this.currentDate = new Date(
this.currentDate.getFullYear(),
this.currentDate.getMonth() - 1,
1
)
},
nextMonth() {
this.currentDate = new Date(
this.currentDate.getFullYear(),
this.currentDate.getMonth() + 1,
1
)
},
selectDate(date) {
if (date.isCurrentMonth) {
this.selectedDate = new Date(
this.currentDate.getFullYear(),
this.currentDate.getMonth(),
date.day
)
}
}
}
}
</script>
事件管理
为日历添加事件显示功能:
<template>
<div
v-for="(date, index) in visibleDates"
:key="index"
@click="selectDate(date)">
{{ date.day }}
<div
v-for="event in getEvents(date)"
:key="event.id"
class="event">
{{ event.title }}
</div>
</div>
</template>
<script>
export default {
methods: {
getEvents(date) {
return this.events.filter(event => {
const eventDate = new Date(event.date)
return eventDate.getDate() === date.day &&
eventDate.getMonth() === this.currentDate.getMonth()
})
}
}
}
</script>
以上方法提供了从简单到复杂的日历实现方案,可根据项目需求选择适合的方式。第三方库适合快速集成,手动实现则更灵活可控。






