最近在做 vue 微信公众号项目, 有个自定义日历控件展示的需求,经过查阅资料,最终实现了如图所示效果,这里做了总结,需要的小伙伴可以参考一下:
HTML代码:
<template><div class="pageContainer"><div class="vanCalendar"><div class="topTitle"><div class="topYear">{{ new Date().getFullYear() }}</div>{{ new Date().getMonth() + 1 }}月</div><van-calendarref="calendar"color="#1989fa":formatter="formatter":min-date="minDate":max-date="maxDate":show-title="false":show-mark="false":show-subtitle="false":poppable="false":show-confirm="false"@select="onCalendarSelect"/></div></div>
</template>
JS代码:
<script>
export default {data() {return {dateList: [],minDate: "",maxDate: "",};},created() {const currentDate = new Date();const year = currentDate.getFullYear();const month = currentDate.getMonth();this.minDate = new Date(year, month, 1);this.maxDate = new Date(year, month, this.getLastDayOfMonth());// 模拟异步请求setTimeout(() => {this.dateList = [{ date: "2024/06/01", status: "0" },{ date: "2024/06/02", status: "0" },{ date: "2024/06/03", status: "1" },{ date: "2024/06/04", status: "1" },{ date: "2024/06/05", status: "2" },{ date: "2024/06/06", status: "2" },{ date: "2024/06/07", status: "2" },{ date: "2024/06/08", status: "2" },{ date: "2024/06/09", status: "2" },{ date: "2024/06/10", status: "1" },{ date: "2024/06/11", status: "1" },{ date: "2024/06/12", status: "1" },{ date: "2024/06/13", status: "1" },{ date: "2024/06/14", status: "1" },{ date: "2024/06/15", status: "0" },{ date: "2024/06/16", status: "0" },{ date: "2024/06/17", status: "1" },{ date: "2024/06/18", status: "1" },{ date: "2024/06/19", status: "1" },{ date: "2024/06/20", status: "1" },{ date: "2024/06/21", status: "1" },{ date: "2024/06/22", status: "0" },{ date: "2024/06/23", status: "0" },{ date: "2024/06/24", status: "2" },{ date: "2024/06/25", status: "2" },{ date: "2024/06/26", status: "1" },{ date: "2024/06/27", status: "1" },{ date: "2024/06/28", status: "1" },{ date: "2024/06/29", status: "0" },{ date: "2024/06/30", status: "0" },];});},methods: {// 自定义日期文案formatter(day) {let isHasData = 0;let dayTimestamp = this.formattedDateFunc(day.date);this.dateList.forEach((item) => {if (dayTimestamp == item.date) {isHasData = item.status;}});// status=1,日期下方添加黄点if (isHasData == 1) {day.className = "addOrangeDot";}// status=2,日期下方添加绿点if (isHasData == 2) {day.className = "addGreenDot";}// 当前选中的日期if (day.type == "selected") {if (isHasData == 1) {// 给选中的日期加上蓝色实心圆,且status=1,日期下方添加黄点day.className = "selectedDay addOrangeDot";}if (isHasData == 2) {// 给选中的日期加上蓝色实心圆,且status=2,日期下方添加绿点day.className = "selectedDay addGreenDot";}}// 当天日期if (dayTimestamp == this.formattedDateFunc()) {if (isHasData == 1) {// 给当天加上蓝色空心圆,且status=1,日期下方添加黄点day.className = "addOrangeDot calendarToday";}if (isHasData == 2) {// 给当天加上蓝色空心圆,且status=2,日期下方添加绿点day.className = "addGreenDot calendarToday";}}return day;},// 日期被选中时触发的方法onCalendarSelect(val) {this.$toast("当前选中日期:" + this.formattedDateFunc(val, "-"));},// 获取当月的最后一天getLastDayOfMonth() {const date = new Date();const year = date.getFullYear();const month = date.getMonth();const lastDay = new Date(year, month + 1, 0).getDate();return lastDay;},// 日期格式化formattedDateFunc(timestamp, type = "/") {const currentDate = timestamp ? new Date(timestamp) : new Date();const year = currentDate.getFullYear();let month = currentDate.getMonth() + 1;let day = currentDate.getDate();month = month < 10 ? `0${month}` : month;day = day < 10 ? `0${day}` : day;return `${year}${type}${month}${type}${day}`;},},
};
</script>
CSS代码:
<style lang="scss" scoped>
.pageContainer {height: calc(100vh - 68px);background: #fff;font-size: 18px;overflow: auto;.vanCalendar {::v-deep .van-calendar__month-title {display: none;}::v-deep .van-calendar__header {box-shadow: none;}//有数据日期加点.addGreenDot,.addOrangeDot {position: relative;}// 绿点::v-deep .addGreenDot::after {position: absolute;content: "";width: 6px;height: 6px;top: 56px;left: 25px;border-radius: 50%;background-color: rgb(34, 177, 76);}// 黄点::v-deep .addOrangeDot::after {position: absolute;content: "";width: 6px;height: 6px;top: 56px;left: 25px;border-radius: 50%;background-color: #ff822c;}//当天日期::v-deep .calendarToday {position: relative;}// 当天日期添加空心蓝色圆::v-deep .calendarToday::before {width: 40px;height: 40px;line-height: 40px;position: absolute;top: 11px;left: 9px;content: "";text-align: center;font-size: 30px;border-radius: 50%;border: 2px solid rgb(25, 137, 250);}//选中的日期::v-deep .selectedDay {position: relative;}::v-deep .selectedDay::before {width: 40px;height: 40px;line-height: 40px;position: absolute;top: 12px;left: 8.6px;content: "";text-align: center;font-size: 30px;border-radius: 50%;border: none;}//选中的日期添加实心蓝色圆::v-deep .van-calendar__selected-day {border-radius: 50%;background: #59afff;z-index: 2;position: absolute;border: none;}::v-deep .van-calendar__selected-day::after {background-color: #fff !important;}::v-deep .van-calendar__header-subtitle {display: none;}::v-deep .van-calendar__selected-day {width: 40px;height: 40px;}}.topTitle {position: relative;padding: 10px;text-align: center;background: #fff;font-size: 24px;font-weight: bold;}.topYear {position: absolute;left: 0;font-weight: normal;}
}
</style>