效果如下:
<template>
<div class="calendar">
<div class="header">
<button @click="previousMonth"><</button>
<h2>{{ currentYear }}-{{ currentMonth }} </h2>
<button @click="nextMonth">></button>
</div>
<div class="days">
<div v-for="day in daysOfWeek" :key="day" class="week">{{ day }}</div>
<div v-for="blank in firstDayOfMonth" :key=" 'black'+blank" class="day"></div>
<div
v-for="(date, index) in daysInMonth"
:key="index"
class="day"
:class="{ 'marked-date': isMarkedNowDate(date) }"
>
<span :style="{ color: isMarkedDate(date) ? '#73DE07' : 'white' }">{{ date.getDate() }}</span>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Calendar',
props: {
// markedDates: {
// type: Array,
// default: () => []
// }
},
data() {
return {
currentDate: new Date(),
currentYear: '',
currentMonth: '',
markedDates: ['2024-06-16', '2024-06-15', '2024-06-01'],
daysOfWeek: ['日', '一', '二', '三', '四', '五', '六'],
firstDayOfMonth: 0,
daysInMonth: []
};
},
mounted() {
this.updateMonthAndYear();
this.daysInMonths();
this.firstDayOfMonths();
},
methods: {
firstDayOfMonths() {
// getDay() 方法可返回一周(0~6)的某一天的数字。
// 注意: 星期天为 0, 星期一为 1, 以此类推。
const firstDay = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth(), 1).getDay();
this.firstDayOfMonth = firstDay === 0 ? 0 : firstDay; // Adjusting for Sunday being the first day
},
daysInMonths() {
this.daysInMonth = [];
const firstDay = new Date(this.currentYear, this.currentDate.getMonth(), 1);
const lastDay = new Date(this.currentYear, this.currentDate.getMonth() + 1, 0);
let currentDay = firstDay;
while (currentDay <= lastDay) {
this.daysInMonth.push(new Date(currentDay));
currentDay.setDate(currentDay.getDate() + 1);
}
},
updateMonthAndYear() {
this.currentYear = this.currentDate.getFullYear();
this.currentMonth = this.pad(this.currentDate.getMonth() + 1);
},
pad(num) {
return num < 10 ? '0' + num : num;
},
isMarkedDate(date) {
const formattedDate = `${date.getFullYear()}-${this.pad(date.getMonth() + 1)}-${this.pad(date.getDate())}`;
return this.markedDates.includes(formattedDate);
},
isMarkedNowDate(date) {
const now = new Date();
const nowDate = `${now.getFullYear()}-${this.pad(now.getMonth() + 1)}-${this.pad(now.getDate())}`;
const formattedDate = `${date.getFullYear()}-${this.pad(date.getMonth() + 1)}-${this.pad(date.getDate())}`;
return nowDate==formattedDate;
},
previousMonth() {
this.currentDate.setMonth(this.currentDate.getMonth() - 1);
this.firstDayOfMonths();
this.updateMonthAndYear();
this.daysInMonths()
},
nextMonth() {
this.currentDate.setMonth(this.currentDate.getMonth() + 1);
this.firstDayOfMonths();
this.updateMonthAndYear();
this.daysInMonths()
}
}
};
</script>
<style scoped>
.calendar {
width: 4.5455rem;
padding: .1818rem;
}
.header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: .1818rem;
color: white;
}
.days {
display: grid;
grid-template-columns: repeat(7, 1fr);
}
.week {
padding: .0909rem;
text-align: center;
color: #b9c9dd80;
}
.day {
padding: .0909rem;
text-align: center;
color: white;
}
.marked-date {
background: #00A6FF;
border-radius: .0727rem;
}
</style>