使用场景:左右箭头可以切换年,上个月和下个月可以切换月份,左侧日期显示同步变化,当天是橘色的那个颜色,其他的需要传数组,看哪天有数据需要在日历上打那个蓝色的点儿
源码:
<template>
<div class="calendar">
<van-calendar class="calendar-main" :min-date="minDate" :max-date="maxDate" :poppable="false" :show-confirm="false"
:show-mark="false" :default-date="defaultDate" first-day-of-week="1" row-height="35px" :formatter="formatter"
ref="calendar">
<template #title>
<div class="calendar-top">
<div class="calendar-top-time">
{{ year }}年{{ month + 1 }}月
</div>
<div class="calendar-top-button">
<van-icon name="arrow-left" class="button-icon" @click="arrowLeft()" />
<div :style="{ color: isClickLastYear ? '' : 'grey' }" @click="lastYear">上个月</div>
<div @click="currentYear">本月</div>
<div :style="{ color: isClickNextYear ? '' : 'grey' }" @click="nextYear">下个月</div>
<van-icon name="arrow" class="button-icon" @click="arrowRight()" />
</div>
</div>
</template>
</van-calendar>
</div>
</template>
<script>
export default {
data () {
return {
defaultDate: null,
today: new Date(),
year: new Date().getFullYear(),
month: new Date().getMonth(),
minDate: null,
maxDate: null,
isClickLastYear: true,
isClickNextYear: true,
dayDatas:['2024-11-1']
}
},
created () {
this.year = this.today.getFullYear()
this.month = this.today.getMonth()
this.setDate()
},
methods: {
formatter (day) {
//给有数据的日期加点
if (this.dayDatas && this.dayDatas.length > 0) {
this.dayDatas.forEach(item => {
if (new Date(item).getTime() == day.date.getTime()) {
day.className = "addDot"
}
})
}
//当天日期加样式
if (day.date.toDateString() == this.today.toDateString()) {
day.className = "calendarToday"
}
return day
},
//设置当前显示日历
setDate () {
const daycount = new Date(this.year, this.month + 1, 0).getDate()
let monthMin = new Date(this.year, this.month, 1)
let monthMax = new Date(this.year, this.month, daycount)
this.minDate = monthMin
this.maxDate = monthMax
},
//切换上年
arrowLeft () {
this.year--
this.setDate()
},
//切换上月
lastYear () {
if (this.month > 0) {
this.month--
this.setDate()
if (this.month > 0) {
this.isClickLastYear = true
} else {
this.isClickLastYear = false
}
if (!this.isClickNextYear) {
this.isClickNextYear = true
}
}
},
//切换下年
arrowRight () {
this.year++
this.setDate()
},
//切换下月
nextYear () {
if (this.month < 11) {
this.month++
this.setDate()
if (this.month < 11) {
this.isClickNextYear = true
} else {
this.isClickNextYear = false
}
if (!this.isClickLastYear) {
this.isClickLastYear = true
}
}
},
currentYear () {
this.month = this.today.getMonth()
this.setDate()
}
}
}
</script>
<style lang="less" scoped>
.calendar {
// border: 1px solid red;
margin-bottom: 46px !important;
.calendar-top {
margin-bottom: 16px;
display: flex;
justify-content: space-between;
.calendar-top-time {
color: #000;
margin: 0 10px;
}
.calendar-top-button {
display: flex;
font-size: 14px;
align-items: center;
gap: 8px;
color: #59afff;
.button-icon {
width: 16px;
height: 16px;
line-height: 16px;
background: #d9e6ff;
border-radius: 50%;
}
}
}
.calendar-weekdays {
display: flex;
height: 50px;
justify-content: space-between;
align-items: center;
// border: 1px solid red;
.calendar-weekdays-item {
width: 50px;
font-size: 20px;
color: rgba(0, 0, 0 0.5);
// border: 1px solid red
}
}
.calendar-days {
display: grid;
grid-template-columns: repeat(7, 8%);
grid-row-gap: 14px;
height: 50px;
justify-content: space-between;
align-items: center;
.calendar-days-item {
flex-shrink: 0;
width: 50px;
font-size: 28px;
color: #000000;
// border: 1px solid red;
}
}
}
/deep/.van-calendar {
width: 100%;
margin-left: -3%;
background: none;
}
/deep/.van-calendar__body {
overflow: hidden;
}
/deep/.van-calendar__header {
box-shadow: none;
}
// /deep/(.van-calendar__day) {
// margin-bottom: 6px !important;
// }
/deep/.van-calendar__selected-day {
border-radius: 50%;
background-color: #59afff;
// background-color: #ffae34;
z-index: 2;
position: absolute;
}
/deep/.van-calendar__selected-day::after {
background-color: #fff !important;
}
/deep/.van-calendar__header-subtitle {
display: none !important;
}
/deep/.van-calendar__weekday {
color: rgba(0, 0, 0 0.5);
}
/deep/.van-calendar__weekday::before {
content: "周";
color: rgba(0, 0, 0 0.5);
}
//有数据日期加点
/deep/.addDot {
position: relative;
}
/deep/.addDot::after {
position: absolute;
content: "";
width: 6px;
height: 6px;
top: 28Px;
// left: 45px;
border-radius: 50%;
background-color: #0084ff;
}
// 当天日期
/deep/.calendarToday {
position: relative;
color: #fff;
// font-size: 0;
// z-index: 1;
}
/deep/.calendarToday::before {
width: 35Px;
height: 35Px;
line-height: 35Px;
position: absolute;
top: 0;
content: "今";
text-align: center;
font-size: 15px;
border-radius: 50%;
background-color: #ffae34;
// z-index: -1;
}
//当天日期并且有数据
/deep/.addDot_calendarToday::after {
position: absolute;
content: "";
width: 12px;
height: 12px;
top: 26Px;
left: 45px;
border-radius: 50%;
background-color: #fff;
z-index: 4;
}
/deep/.addDot_calendarToday::before {
width: 35Px;
height: 35Px;
line-height: 35Px;
position: absolute;
top: 0;
content: "今";
text-align: center;
font-size: 15px;
border-radius: 50%;
color: #fff;
background-color: #ffae34;
}
//有数据并且被选中
/deep/.addDot_Select::after {
position: absolute;
content: "";
width: 12px;
height: 12px;
top: 26Px;
left: 45px;
border-radius: 50%;
background-color: #fff;
z-index: 3;
}
//被选中显示的今字
/deep/.calendarToday .van-calendar__selected-day {
font-size: 0;
}
/deep/.calendarToday .van-calendar__selected-day::before {
content: "今";
z-index: 9;
font-size: 15px;
height: 35Px;
line-height: 35Px;
}
/deep/.addDot_calendarToday .van-calendar__selected-day {
font-size: 0;
}
/deep/.addDot_calendarToday .van-calendar__selected-day::before {
content: "今";
z-index: 9;
font-size: 15px;
height: 35Px;
line-height: 35Px;
}
</style>
参考文章:https://blog.youkuaiyun.com/weixin_46687032/article/details/126508816?spm=1001.2014.3001.5501