vue实现年历
Vue 实现年历的方法
使用 Vue 实现年历可以通过组件化开发方式,结合日期计算和动态渲染完成。以下是两种常见的实现方式:
基于原生 Vue 的日历组件
创建 Calendar.vue 组件文件,核心逻辑包括日期计算和模板渲染:
<template>
<div class="calendar">
<div class="header">{{ currentYear }}年</div>
<div class="months">
<div v-for="month in 12" :key="month" class="month">
<div class="month-title">{{ month }}月</div>
<div class="days">
<div v-for="day in getDaysInMonth(currentYear, month)"
:key="day"
class="day">
{{ day }}
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
currentYear: new Date().getFullYear()
}
},
methods: {
getDaysInMonth(year, month) {
return new Date(year, month, 0).getDate()
}
}
}
</script>
<style>
.calendar {
font-family: Arial;
width: 100%;
}
.months {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
}
.month {
border: 1px solid #ddd;
padding: 10px;
}
.days {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 5px;
}
.day {
text-align: center;
padding: 5px;
}
</style>
使用第三方库 vue-cal
安装 vue-cal 库可以快速实现高级日历功能:

npm install vue-cal @vueuse/core
组件实现示例:
<template>
<vue-cal
:time="false"
:disable-views="['week', 'day']"
active-view="year"
:events="events"
@ready="onCalendarReady"
/>
</template>
<script>
import VueCal from 'vue-cal'
import 'vue-cal/dist/vuecal.css'
export default {
components: { VueCal },
data() {
return {
events: [
{ start: '2023-01-15', end: '2023-01-15', title: '假期' },
{ start: '2023-07-01', end: '2023-07-01', title: '纪念日' }
]
}
},
methods: {
onCalendarReady() {
console.log('Calendar ready')
}
}
}
</script>
实现功能扩展
添加月份切换功能
在原生实现中增加年份切换按钮:

<template>
<div>
<button @click="prevYear">上一年</button>
<span>{{ currentYear }}</span>
<button @click="nextYear">下一年</button>
<!-- 日历内容 -->
</div>
</template>
<script>
export default {
methods: {
prevYear() {
this.currentYear--
},
nextYear() {
this.currentYear++
}
}
}
</script>
添加事件标记功能
为特定日期添加样式标记:
<template>
<div class="day"
:class="{ 'has-event': hasEvent(currentYear, month, day) }">
{{ day }}
</div>
</template>
<script>
export default {
data() {
return {
markedDates: ['2023-01-01', '2023-10-01']
}
},
methods: {
hasEvent(year, month, day) {
const dateStr = `${year}-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`
return this.markedDates.includes(dateStr)
}
}
}
</script>
<style>
.has-event {
background-color: #ffeb3b;
border-radius: 50%;
}
</style>
响应式设计考虑
针对移动端优化布局:
@media (max-width: 768px) {
.months {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 480px) {
.months {
grid-template-columns: 1fr;
}
}






