vue实现日历
Vue 实现日历的基本方法
使用 Vue 实现日历可以通过自定义组件或借助第三方库完成。以下是两种常见实现方式:
自定义日历组件 创建基于 Vue 的日历组件需要处理日期计算和渲染逻辑。核心是生成当月日期数组,并处理跨月日期。
使用第三方库
如 v-calendar 或 fullcalendar-vue 等成熟库可快速实现功能丰富的日历。
自定义日历组件实现步骤
安装依赖(如需日期处理)
npm install date-fns
组件基本结构
<template>
<div class="calendar">
<div class="header">
<button @click="prevMonth">上一月</button>
<h2>{{ currentMonth }}</h2>
<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="(date, index) in days"
:key="index"
:class="{ 'other-month': !date.isCurrentMonth }"
@click="selectDate(date)"
>
{{ date.day }}
</div>
</div>
</div>
</template>
核心逻辑

import { format, addMonths, getDaysInMonth, startOfMonth, getDay } from 'date-fns'
export default {
data() {
return {
currentDate: new Date(),
weekdays: ['日', '一', '二', '三', '四', '五', '六']
}
},
computed: {
currentMonth() {
return format(this.currentDate, 'yyyy年MM月')
},
days() {
const daysInMonth = getDaysInMonth(this.currentDate)
const startDay = getDay(startOfMonth(this.currentDate))
const days = []
// 上月剩余天数
const prevMonthDays = startDay === 0 ? 6 : startDay - 1
const prevMonth = addMonths(this.currentDate, -1)
const prevMonthLastDay = getDaysInMonth(prevMonth)
for (let i = prevMonthLastDay - prevMonthDays + 1; i <= prevMonthLastDay; i++) {
days.push({
day: i,
date: new Date(prevMonth.getFullYear(), prevMonth.getMonth(), i),
isCurrentMonth: false
})
}
// 当月天数
for (let i = 1; i <= daysInMonth; i++) {
days.push({
day: i,
date: new Date(this.currentDate.getFullYear(), this.currentDate.getMonth(), i),
isCurrentMonth: true
})
}
// 下月天数补全
const remainingDays = 42 - days.length
const nextMonth = addMonths(this.currentDate, 1)
for (let i = 1; i <= remainingDays; i++) {
days.push({
day: i,
date: new Date(nextMonth.getFullYear(), nextMonth.getMonth(), i),
isCurrentMonth: false
})
}
return days
}
},
methods: {
prevMonth() {
this.currentDate = addMonths(this.currentDate, -1)
},
nextMonth() {
this.currentDate = addMonths(this.currentDate, 1)
},
selectDate(date) {
this.$emit('date-selected', date)
}
}
}
基础样式
.calendar {
width: 350px;
font-family: Arial;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.weekdays {
display: grid;
grid-template-columns: repeat(7, 1fr);
text-align: center;
font-weight: bold;
}
.days {
display: grid;
grid-template-columns: repeat(7, 1fr);
grid-gap: 5px;
}
.days > div {
padding: 10px;
text-align: center;
cursor: pointer;
}
.days > div:hover {
background: #eee;
}
.other-month {
color: #ccc;
}
使用 v-calendar 库实现
安装 v-calendar
npm install v-calendar
全局注册
import VCalendar from 'v-calendar'
import 'v-calendar/dist/style.css'
Vue.use(VCalendar)
组件使用

<template>
<v-calendar
:attributes="attributes"
@dayclick="onDayClick"
/>
</template>
<script>
export default {
data() {
return {
attributes: [
{
highlight: 'blue',
dates: new Date()
}
]
}
},
methods: {
onDayClick(day) {
console.log('Selected date:', day.date)
}
}
}
</script>
日历功能扩展建议
事件标记 在日期上显示事件或标记,可通过在日期数据中添加事件属性实现。
范围选择 实现日期范围选择功能,需要处理开始日期和结束日期的逻辑。
国际化 支持多语言周显示和日期格式,可使用 date-fns 的 locale 功能。
主题定制 通过 CSS 变量或预处理器定制日历样式,适应不同设计需求。
移动端适配 添加触摸事件支持,优化小屏幕显示效果。






