vue实现日历组件
实现基础日历结构
使用 Vue 的模板和逻辑分离特性,构建日历的网格布局。通过 v-for 循环渲染日期格子,动态计算当前月份的天数和起始星期位置。
<template>
<div class="calendar">
<div class="header">
<button @click="prevMonth">上一月</button>
<h3>{{ currentYear }}年 {{ currentMonth + 1 }}月</h3>
<button @click="nextMonth">下一月</button>
</div>
<div class="weekdays">
<span v-for="day in ['日', '一', '二', '三', '四', '五', '六']" :key="day">{{ day }}</span>
</div>
<div class="days">
<span
v-for="(day, index) in days"
:key="index"
:class="{ 'other-month': !day.isCurrentMonth }"
>
{{ day.date }}
</span>
</div>
</div>
</template>
处理日期逻辑
通过 JavaScript 的 Date 对象计算月份天数、起始星期,并生成日期数组。使用 computed 属性动态更新数据。
<script>
export default {
data() {
return {
currentYear: new Date().getFullYear(),
currentMonth: new Date().getMonth(),
};
},
computed: {
days() {
const firstDay = new Date(this.currentYear, this.currentMonth, 1).getDay();
const daysInMonth = new Date(this.currentYear, this.currentMonth + 1, 0).getDate();
const days = [];
// 填充上个月末尾的日期
for (let i = 0; i < firstDay; i++) {
days.push({ date: '', isCurrentMonth: false });
}
// 填充当前月日期
for (let i = 1; i <= daysInMonth; i++) {
days.push({ date: i, isCurrentMonth: true });
}
return days;
}
},
methods: {
prevMonth() {
if (this.currentMonth === 0) {
this.currentYear--;
this.currentMonth = 11;
} else {
this.currentMonth--;
}
},
nextMonth() {
if (this.currentMonth === 11) {
this.currentYear++;
this.currentMonth = 0;
} else {
this.currentMonth++;
}
}
}
};
</script>
添加样式与交互
通过 CSS 美化日历布局,并为日期格子添加悬停和点击效果。使用 Vue 的事件绑定实现日期选择功能。
<style scoped>
.calendar {
width: 300px;
border: 1px solid #eee;
font-family: Arial, sans-serif;
}
.header {
display: flex;
justify-content: space-between;
padding: 10px;
background: #f5f5f5;
}
.weekdays {
display: grid;
grid-template-columns: repeat(7, 1fr);
text-align: center;
background: #eee;
}
.days {
display: grid;
grid-template-columns: repeat(7, 1fr);
grid-gap: 5px;
padding: 5px;
}
.days span {
padding: 10px;
text-align: center;
cursor: pointer;
}
.days span:hover {
background: #f0f0f0;
}
.other-month {
color: #ccc;
}
</style>
扩展功能:日期选择与事件标记
通过 v-model 绑定选中的日期,并支持添加自定义事件。新增一个 events 数据对象存储事件信息。
data() {
return {
events: {},
selectedDate: null,
};
},
methods: {
selectDate(day) {
if (day.isCurrentMonth) {
this.selectedDate = new Date(this.currentYear, this.currentMonth, day.date);
}
},
addEvent(eventText) {
if (!this.selectedDate) return;
const dateKey = this.selectedDate.toISOString().split('T')[0];
this.events[dateKey] = eventText;
}
}
在模板中添加事件输入框和显示逻辑:

<div class="events">
<input v-model="newEvent" @keyup.enter="addEvent" placeholder="添加事件" />
<div v-if="selectedDate">
{{ events[selectedDate.toISOString().split('T')[0]] || '无事件' }}
</div>
</div>






