一 Calendar 日历
Vant4.x版本提供了switch-mode属性,里面刚好可以满足我们的需求,但适用于Vue3开发,所以我们还得自己动手。先看一下Calendar里面的属性
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
type | 选择类型:single表示选择单个日期,multiple表示选择多个日期,range表示选择日期区间 | string | single |
title | 日历标题 | string | 日期选择 |
color | 主题色,对底部按钮和选中日期生效 | string | #ee0a24 |
min-date | 可选择的最小日期 | Date | 当前日期 |
max-date | 可选择的最大日期 | Date | 当前日期的六个月后 |
default-date | 默认选中的日期,type 为 multiple 或 range 时为数组,传入 null 表示默认不选择 | Date | Date[] |
row-height | 日期行高 | number | string |
formatter | 日期格式化函数 | (day: Day) => Day | - |
poppable | 是否以弹层的形式展示日历 | boolean | true |
lazy-render | 是否只渲染可视区域的内容 | boolean | true |
show-mark | 是否显示月份背景水印 | boolean | true |
show-title | 是否展示日历标题 | boolean | true |
show-subtitle | 是否展示日历副标题(年月) | boolean | true |
show-confirm | 是否展示确认按钮 | boolean | true |
readonly | 是否为只读状态,只读状态下不能选择日期 | boolean | true |
confirm-text | 确认按钮的文字 | string | 确定 |
confirm-disabled-text | 确认按钮处于禁用状态时的文字 | string | 确定 |
first-day-of-week | 设置周起始日 | 0-6 | 0 |
二 需求
如图所示只显示一个月份,页面上通过点击左右按钮来实现对月份的切换。实现是将min-date设置月份的第一天,max-date设置为月份的最后一天
三 完整代码
<div class="main-clock-calendar">
<div class="main-clock-calendar-title">签到详情</div>
<div class="calendar-div">
<van-calendar
:poppable="false"
:show-subtitle="false"
:show-confirm="false"
type="multiple"
:min-date="minDate"
:max-date="maxDate"
:default-date="defaultDate"
first-day-of-week="1"
lazy-render
show-subtitle
readonly
>
<div slot="title" class="title-box">
<div @click="arrowLeft(1)"><img class="title-box-left" src="@/assets/clock/left.png" alt=""></div>
{{ calendarTitle }}
<div @click="arrowRight(1)"><img class="title-box-right" src="@/assets/clock/right.png" alt=""></div>
</div>
</van-calendar>
</div>
</div>
getClient() {
this.$store.dispatch('clock/requestQueryClockClient', {clockId: this.clockId})
.then((data) => {
this.client = data
const nowTime = new Date()
const year = nowTime.getFullYear()
const month = nowTime.getMonth()
this.calendarTitle = year + '年' + (month + 1) + '月'
this.minDate = new Date(year, month, 1)
this.maxDate = new Date(year, month + 1, 0)
this.isClock = isToday(data.recentClockInTime)
this.getClockTask()
this.getClockInTime()
this.initEnterClientTag()
})
},
//获取客户的打卡时间,将打卡时间都转化成date类型,再push到default-date数组中
getClockInTime() {
this.$store.dispatch('clock/requestQueryClockInTime', {clockId: this.clockId})
.then((data) => {
data.forEach((item => {
const nowDay = new Date(item)
const year = nowDay.getFullYear()
const month = nowDay.getMonth()
const day = nowDay.getDate()
this.defaultDate.push(new Date(year, month, day))
}))
})
},
arrowLeft(e) {
let nowTime = new Date(this.minDate)
let year = nowTime.getFullYear()
let month = nowTime.getMonth() - e
if ((month + 1) === 0) {
this.calendarTitle = (year - 1) + '年' + (12) + '月'
} else {
this.calendarTitle = year + '年' + (month + 1) + '月'
}
this.minDate = new Date(year, month, 1)
this.maxDate = new Date(year, month + 1, 0)
},
arrowRight(e) {
let nowTime = new Date(this.minDate)
let year = nowTime.getFullYear()
let month = nowTime.getMonth() + e
if (month + 1 > 12) {
this.calendarTitle = (year + 1) + '年' + (1) + '月'
} else {
this.calendarTitle = year + '年' + (month + 1) + '月'
}
this.minDate = new Date(year, month, 1)
this.maxDate = new Date(year, month + 1, 0)
},
css 部分
.main-clock-calendar {
width: 8.933rem;
height: 9.3rem;
opacity: 1;
background: url('../../assets/clock/calendar-bgc.png');
background-size: 100% 100%;
margin: 0.427rem 0.533rem 0.533rem 0.533rem;
.main-clock-calendar-title {
font-size: 0.373rem;
font-family: PingFang SC-Medium, PingFang SC, sans-serif;
font-weight: 500;
color: #000000;
line-height: 0.48rem;
padding: 0.533rem 0 0 0.32rem;
}
.calendar-div {
::v-deep .van-calendar {
height: 7.8rem !important;
margin-top: 0.233rem;
}
::v-deep .van-calendar__days {
align-items: center;
justify-content: flex-end;
}
::v-deep .van-calendar__day--start {
width: 0.64rem;
height: 0.64rem !important;
background: #FE6651;
margin: 0.31rem;
box-sizing: border-box;
border-radius: 0.107rem 0.107rem 0.107rem 0.107rem;
opacity: 1;
}
::v-deep .van-calendar__day--multiple-middle {
width: 0.64rem;
height: 0.64rem !important;
background: #FE6651;
margin: 0.31rem;
box-sizing: border-box;
border-radius: 0.107rem 0.107rem 0.107rem 0.107rem;
opacity: 1;
}
::v-deep .van-calendar__day--end {
width: 0.64rem;
height: 0.64rem !important;
background: #FE6651;
margin: 0.31rem;
box-sizing: border-box;
border-radius: 0.107rem 0.107rem 0.107rem 0.107rem;
opacity: 1;
}
::v-deep .van-calendar__day {
height: 0.967rem;
}
::v-deep .van-calendar__header-subtitle {
font-size: 0.48rem;
font-family: PingFang SC-Medium, PingFang SC, sans-serif;
font-weight: 500;
color: #000000;
line-height: 0.96rem;
}
::v-deep .van-calendar__header {
box-shadow: 0 2px 5px rgba(125, 126, 128, .16) !important;
}
.van-icon-cross::before {
content: '';
}
::v-deep .van-calendar__day--multiple-selected {
width: 0.64rem;
height: 0.64rem !important;
background: #FE6651;
margin: 0 3.3%;
border-radius: 0.107rem 0.107rem 0.107rem 0.107rem;
opacity: 1;
}
::v-deep .van-calendar__header-subtitle {
display: none;
}
.title-box {
display: flex;
justify-content: space-between;
.title-box-left {
width: 0.32rem;
height: 0.32rem;
margin-left: 0.32rem;
cursor: pointer;
}
.title-box-right {
width: 0.32rem;
height: 0.32rem;
margin-right: 0.32rem;
cursor: pointer;
}
}
}
::v-deep .van-calendar__day:last-child {
margin-right: auto!important;
}
}