倒叙日历:
<template><div class="date-picker"><div class="column" @wheel="onYearScroll"><div v-for="(year, index) in displayedYears" :key="index" :class="{current: year === currentYear.value && index === 1}">{{ year }}</div></div><div class="column" @wheel="onMonthScroll"><div v-for="(month, index) in displayedMonths" :key="index" :class="{current: month === currentMonth.value && index === 1}">{{ monthString(month) }}</div></div><div class="column" @wheel="onDayScroll"><div v-for="(day, index) in displayedDays" :key="index" :class="{current: day === currentDay.value && index === 1}">{{ dayString(day) }}</div></div></div>
</template><script setup>
import { ref, computed } from 'vue'const currentYear = ref(new Date().getFullYear())
const currentMonth = ref(new Date().getMonth() + 1)
const currentDay = ref(new Date().getDate())const displayedYears = computed(() => {const year = currentYear.valuereturn [year + 1, year, year - 1, year - 2]
})const displayedMonths = computed(() => {const month = currentMonth.valuereturn [(month + 1 - 1) % 12 + 1,month,(month - 1 + 12) % 12 || 12,(month - 2 + 12) % 12 || 12,]
})const daysInMonth = (year, month) => {return new Date(year, month, 0).getDate()
}const displayedDays = computed(() => {const year = currentYear.valueconst month = currentMonth.valueconst day = currentDay.valueconst daysInCurrentMonth = daysInMonth(year, month)return [(day + 1 - 1) % daysInCurrentMonth + 1,day,(day - 1 + daysInCurrentMonth - 1) % daysInCurrentMonth + 1,(day - 2 + daysInCurrentMonth - 1) % daysInCurrentMonth + 1]
})const onYearScroll = (event) => {event.preventDefault()if (event.deltaY < 0) {currentYear.value += 1} else {currentYear.value -= 1}// Reset month and day to 1currentMonth.value = 1currentDay.value = 1
}const onMonthScroll = (event) => {event.preventDefault()if (event.deltaY < 0) {currentMonth.value = (currentMonth.value % 12) + 1} else {currentMonth.value = (currentMonth.value - 1 + 11) % 12 + 1}// Reset day to 1currentDay.value = 1
}const onDayScroll = (event) => {event.preventDefault()const year = currentYear.valueconst month = currentMonth.valueconst daysInCurrentMonth = daysInMonth(year, month)if (event.deltaY < 0) {currentDay.value = (currentDay.value % daysInCurrentMonth) + 1} else {currentDay.value = (currentDay.value - 1 + daysInCurrentMonth - 1) % daysInCurrentMonth + 1}
}const monthString = (month) => {return month.toString().padStart(2, '0')
}const dayString = (day) => {return day.toString().padStart(2, '0')
}
</script><style>
.date-picker {display: flex;justify-content: center;align-items: center;gap: 20px;color: #fff !important;
}
.column {display: flex;flex-direction: column;align-items: center;width: 60px;
}
.column div {height: 30px;display: flex;justify-content: center;align-items: center;
}
.current {font-weight: bold;color: red;
}
</style>
正序日历:
<template><div class="date-picker"><div class="column" @wheel="onYearScroll"><div v-for="(year, index) in displayedYears" :key="index" :class="{current: year === currentYear}">{{ year }}</div></div><div class="column" @wheel="onMonthScroll"><div v-for="(month, index) in displayedMonths" :key="index" :class="{current: month === currentMonth}">{{ monthString(month) }}</div></div><div class="column" @wheel="onDayScroll"><div v-for="(day, index) in displayedDays" :key="index" :class="{current: day === currentDay}">{{ dayString(day) }}</div></div></div></template><script setup>import { ref, computed } from 'vue'const currentYear = ref(new Date().getFullYear())const currentMonth = ref(new Date().getMonth() + 1)const currentDay = ref(new Date().getDate())const displayedYears = computed(() => {const year = currentYear.valuereturn [year - 2, year - 1, year, year + 1, year + 2]})const displayedMonths = computed(() => {const month = currentMonth.valuereturn [(month - 2 + 12) % 12 || 12,(month - 1 + 12) % 12 || 12,month,(month + 1 - 1) % 12 + 1,(month + 2 - 1) % 12 + 1]})const daysInMonth = (year, month) => {return new Date(year, month, 0).getDate()}const displayedDays = computed(() => {const year = currentYear.valueconst month = currentMonth.valueconst day = currentDay.valueconst daysInCurrentMonth = daysInMonth(year, month)return [(day - 2 + daysInCurrentMonth) % daysInCurrentMonth || daysInCurrentMonth,(day - 1 + daysInCurrentMonth) % daysInCurrentMonth || daysInCurrentMonth,day,(day + 1 - 1) % daysInCurrentMonth + 1,(day + 2 - 1) % daysInCurrentMonth + 1]})const onYearScroll = (event) => {event.preventDefault()if (event.deltaY > 0) {currentYear.value += 1} else {currentYear.value -= 1}// Reset month and day to 1currentMonth.value = 1currentDay.value = 1}const onMonthScroll = (event) => {event.preventDefault()if (event.deltaY > 0) {currentMonth.value = (currentMonth.value % 12) + 1} else {currentMonth.value = (currentMonth.value - 1 + 11) % 12 + 1}// Reset day to 1currentDay.value = 1}const onDayScroll = (event) => {event.preventDefault()const year = currentYear.valueconst month = currentMonth.valueconst daysInCurrentMonth = daysInMonth(year, month)if (event.deltaY > 0) {currentDay.value = (currentDay.value % daysInCurrentMonth) + 1} else {currentDay.value = (currentDay.value - 1 + daysInCurrentMonth - 1) % daysInCurrentMonth + 1}}const monthString = (month) => {return month.toString().padStart(2, '0')}const dayString = (day) => {return day.toString().padStart(2, '0')}</script><style>.date-picker {display: flex;justify-content: center;align-items: center;gap: 20px;color: #fff !important;}.column {display: flex;flex-direction: column;align-items: center;width: 60px;}.column div {height: 30px;display: flex;justify-content: center;align-items: center;}.current {font-weight: bold;color: red;}</style>