在线预览地址
https://tomorrowzjz.github.io/my-vue-sfc-demo/
源码
<!-- Calendar.vue -->
<template>
<div class="calendar">
<div class="header">
<button @click="prevMonth"><</button>
<h2>{{ currentDate }}</h2>
<button @click="nextMonth">></button>
</div>
<table>
<thead>
<tr>
<th v-for="day in daysOfWeek" :key="day">{{ day }}</th>
</tr>
</thead>
<tbody>
<tr v-for="(week, index) in calendar" :key="index">
<td v-for="day in week" :key="day ? day.date.getTime() : 'empty'">
<span v-if="!day.isOtherMonth" @click="day ? selectDate(day) : null" :class="day.date.getTime() === new Date(currentDate+'T00:00:00').getTime()? 'today': ''">{{ day ? day.day : '' }}</span>
<span v-else="day.isOtherMonth" class="other-month">{{ day ? day.day : '' }}</span>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
data() {
return {
daysOfWeek: [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat','Sun'],
currentMonth: new Date(),
calendar: [],
};
},
computed: {
currentDate() {
// let objectDate = this.currentMonth;
// return this.formatDate(objectDate);
// return `${year} - ${month + 1} - ${day}`;
}
},
methods: {
prevMonth() {
this.currentMonth = this.getPreviousMonth(this.currentMonth);
this.generateCalendar();
},
nextMonth() {
this.currentMonth = this.getNextMonth(this.currentMonth);
this.generateCalendar();
},
selectDate(day) {
// 在这里可以添加选中日期的逻辑,比如触发事件或更新组件状态
console.log(`Selected date: ${day.date}`);
alert(`Selected date: ${day.date}`);
},
generateCalendar() {
const currentDate = new Date(); // 获取当前日期
const currentMonth = `${currentDate.getFullYear()}年${currentDate.getMonth() + 1}月`; // 获取当前月份
this.currentMonth = currentMonth;
const firstDayOfMonth = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1); // 当前月的第一天
const startOfWeek = new Date(firstDayOfMonth); // 当前月第一天所在周的第一天
// 确定日历开始的星期一是几号
let firstDayOffset = startOfWeek.getDay() === 0 ? 6 : startOfWeek.getDay() - 1;
// 确定生成日历的第一行
startOfWeek.setDate(startOfWeek.getDate() - firstDayOffset);
let calendar = [];
for (let week = 0; week < 5; week++) {
let days = [];
for (let day = 0; day < 7; day++) {
const date = new Date(startOfWeek.getFullYear(), startOfWeek.getMonth(), startOfWeek.getDate() + week * 7 + day);
days.push({
day: date.getDate(),
date: new Date(date),
isOtherMonth: date.getMonth() !== firstDayOfMonth.getMonth(), // 判断是否属于当前月份
// 这里可以添加更多的信息,比如是否是当前日期等
});
}
calendar.push(days);
}
console.log(calendar)
this.calendar = calendar;
},
getPreviousMonth(date) {
return new Date(date.getFullYear(), date.getMonth() - 1, 1);
},
getNextMonth(date) {
return new Date(date.getFullYear(), date.getMonth() + 1, 1);
},
getOtherMonthDate(day) {
if (day === null) {
// 如果日期为 null,表示当前格子是上一个月或下一个月的日期
const month = this.currentMonth.getMonth();
const year = this.currentMonth.getFullYear();
return this.formatDate(new Date(year, month, 1));
}
return '';
},
formatDate(date) {
// 将日期格式化为 'YYYY-MM-DD' 的字符串
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const day = date.getDate().toString().padStart(2, '0');
return `${year}-${month}-${day}`;
},
},
mounted(){
this.generateCalendar()
}
};
</script>
<style scoped>
/* 添加样式,可以根据需要进行定制 */
.calendar {
font-family: Arial, sans-serif;
text-align: center;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
}
td span {
cursor: pointer;
display: inline-block;
width: 100%;
height: 100%;
text-align: center;
line-height: 30px; /* 调整日期显示的垂直居中 */
}
td span:hover {
background-color: #eee; /* 鼠标悬停时的背景色 */
}
.other-month {
color: #999; /* 使用灰色表示其他月份的日期 */
font-size: 0.8em; /* 调整字体大小 */
}
.today {
color: #606;
font-weight: bold;
}
</style>