vue实现日历功能
基础日历实现
使用Vue实现基础日历功能需要结合日期计算和组件化思想。创建日历组件时,需处理年、月切换并渲染日期格子。
安装依赖(如需要):
npm install date-fns # 推荐日期处理库
日历组件模板部分:
<template>
<div class="calendar">
<div class="header">
<button @click="prevMonth">上个月</button>
<span>{{ currentYear }}年{{ currentMonth }}月</span>
<button @click="nextMonth">下个月</button>
</div>
<div class="weekdays">
<div v-for="day in weekdays" :key="day">{{ day }}</div>
</div>
<div class="days">
<div
v-for="(day, index) in days"
:key="index"
:class="{ 'other-month': !day.isCurrentMonth, 'today': day.isToday }"
>
{{ day.date }}
</div>
</div>
</div>
</template>
日期数据处理
在Vue组件的script部分处理日期逻辑:
import { format, startOfMonth, endOfMonth, eachDayOfInterval, isSameMonth, isToday } from 'date-fns'
export default {
data() {
return {
currentDate: new Date(),
weekdays: ['日', '一', '二', '三', '四', '五', '六']
}
},
computed: {
currentYear() {
return format(this.currentDate, 'yyyy')
},
currentMonth() {
return format(this.currentDate, 'MM')
},
days() {
const start = startOfMonth(this.currentDate)
const end = endOfMonth(this.currentDate)
const daysArray = eachDayOfInterval({ start, end })
return daysArray.map(day => ({
date: format(day, 'd'),
isCurrentMonth: isSameMonth(day, this.currentDate),
isToday: isToday(day),
fullDate: day
}))
}
},
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)
}
}
}
样式设计
基础日历样式可参考以下CSS:
.calendar {
width: 350px;
font-family: Arial;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
}
.weekdays, .days {
display: grid;
grid-template-columns: repeat(7, 1fr);
}
.weekdays div {
padding: 10px;
text-align: center;
font-weight: bold;
}
.days div {
padding: 10px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid #eee;
}
.other-month {
color: #ccc;
}
.today {
background-color: #4285f4;
color: white;
border-radius: 50%;
}
进阶功能实现
事件标记功能
// 在data中添加
events: [
{ date: '2023-06-15', title: '会议' },
{ date: '2023-06-20', title: '生日' }
]
// 修改days计算属性
days() {
// ...原有代码
return daysArray.map(day => {
const formattedDate = format(day, 'yyyy-MM-dd')
return {
// ...原有属性
hasEvent: this.events.some(event => event.date === formattedDate)
}
})
}
模板中添加事件标记
<div class="day-content">
{{ day.date }}
<span v-if="day.hasEvent" class="event-dot"></span>
</div>
添加点击事件
<div @click="selectDay(day)">...</div>
methods: {
selectDay(day) {
this.selectedDate = day.fullDate
// 可以触发自定义事件或显示模态框
}
}
第三方库方案
使用现成的Vue日历组件库可以快速实现复杂功能:
-
安装vue-cal:
npm install vue-cal -
基本使用:
import VueCal from 'vue-cal' import 'vue-cal/dist/vuecal.css'
export default { components: { VueCal }, data() { return { events: [ { start: '2023-06-15 10:00', end: '2023-06-15 12:00', title: '会议' } ] } } }
```html
<vue-cal
:time="false"
:events="events"
active-view="month"
/>
以上方案提供了从零实现和快速集成两种路径,可根据项目复杂度选择适合的方式。自定义实现更适合需要高度定制化的场景,而第三方库适合快速开发标准日历功能。







