效果如下:
<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><divv-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>