前言
学习、练习、用到了dayjs插件来处理日期、icon阿里巴巴矢量库挑选icon、代码基于vue、不依赖任何UI组件库
效果展示
代码
1、template
<template>
<div class="cal">
<!-- 月份选择 -->
<div class="cal_sel">
<select class="cal_sel--select" v-model="curMonth">
<option v-for="mon in sixMonths" :value="mon">{{format(mon)}}加餐日</option>
</select>
<span class="cal_sel--triangle"></span>
</div>
<!-- 周 -->
<ul class="flex cal_week">
<li v-for="wt in weekText" class="square">
<span>{{wt}}</span>
</li>
</ul>
<!-- 日 -->
<ul v-for="weekDays in monDays" class="flex">
<li
v-for="wd in weekDays"
class="square"
:class="{'cal_mark': snackDays.includes(wd.date)}"
@click="clickDay(wd)"
>
<span>{{wd.text}}</span>
</li>
</ul>
<div class="pineapple">
<img src="../assets/pineapple.png" class="pineapple_img img1"/>
<img src="../assets/pineapple.png" class="pineapple_img img2"/>
</div>
</div>
</template>
2、JS
<script>
import dayjs from "dayjs";
import {MonthCalendar, WeekCalendar, RecentMonths} from "./calendar.js";
export default {
name: "calendar",
data() {
return {
monDays: MonthCalendar(),
weekText: WeekCalendar(),
sixMonths: RecentMonths(),//近6月
curMonth: "",//当前所选月份
snackDays: [//加餐日
"2023-12-22", "2023-12-16", "2022-12-17", "2023-12-09",
"2023-11-09", "2023-11-12", "2023-11-19", "2023-11-10",
"2023-10-01", "2023-10-09", "2023-10-21", "2023-10-25",
"2023-09-25", "2023-09-30", "2023-09-20", "2023-09-21"
],
}
},
watch: {
curMonth(val) {
this.monthChange(val);
}
},
created() {
this.curMonth = this.sixMonths[0];
},
methods: {
monthChange(val) {
console.log("monthChange: ", val)
this.monDays = MonthCalendar(val);
console.log(this.monDays);
},
format(val){
return val ? dayjs(val).format("YYYY年M月") : "";
},
clickDay(day) {
console.log(day);
},
}
}
</script>
3、Style
<style scoped>
.cal {
margin: 50px 10px;
padding-bottom: 25px;
border-radius: 4px;
background-image: linear-gradient(180deg, #fff 17%, #fffdfe 27%, #fff6f9 37%, #fef2f6 47%, #ffedf3 60%, #fee9f0 75%, #ffdfea 90%);
font-family: sans-serif;
border: 1px solid #fee9f0;
position: relative;
}
.cal::after {
position: absolute;
content: "";
background: url("src/assets/coffee.png") no-repeat 100% 100%;
width: 70px;
height: 70px;
bottom: 0;
right: 0;
opacity: 0.5;
background-size: 100%;
}
.cal_sel--select {
height: 40px;
margin-left: 12px;
margin-right: 4px;
font-size: 14px;
font-weight: bold;
color: #333;
border: 0;
appearance: none;
background-color: unset;
}
.cal_sel--select:focus {
outline: none;
}
.cal_sel--triangle {
display: inline-block;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 8px solid #333;
}
.flex {
display: flex;
justify-content: flex-start;
align-items: center;
}
.square {
width: calc(100% / 7);
height: 44px;
line-height: 44px;
text-align: center;
z-index: 2;
}
.cal_week {
color: #999;
font-weight: bold;
}
.cal_mark {
background: url("src/assets/favorite.png") no-repeat 100% 100%;
background-position: 50% 50%;
background-size: 75%;
color: #fff;
}
.pineapple {
position: absolute;
height: 40px;
bottom: 0;
opacity: 0.6;
}
.pineapple > .pineapple_img {
display: inline-block;
width: auto;
height: 100%;
}
.pineapple > .img1 {
transform: rotate(45deg);
}
.pineapple > .img2 {
bottom: -10px;
position: absolute;
clip: rect(0, 60px, 30px, 0px);
}
</style>
4、引用JS文件内容
1、calendar.js文件
import dayjs from "dayjs";
/**
* 配置日历月度平面值,获取某月的周、日对应关系
* @param date 基准日期,默认是当前,值获取date所属月份的日历数据
* @param wk 日历顶部周文字,0:代表依次是周日~周六,1:代表依次是周一~周日
* @return [[text: 日文字, date: 日期yyyy-mm-dd]]
* **/
export function MonthCalendar(date = new Date(), wk = 1) {
let weeks = wk === 1 ? [1, 2, 3, 4, 5, 6, 7] : [0, 1, 2, 3, 4, 5, 6];
let daysCal = [];//存放日历二位数组
let lastDay = dayjs(date).endOf('month').date();//获取date月末日数值
let firstDayInWeek = dayjs(date).startOf("month").day();//获取date月初日是周几的数值
let firstDayInWeekIndex = weeks.findIndex(wkIndex => wkIndex === firstDayInWeek);//获取月初日是周几以及在weeks数组的下标
let weekDays = firstDayInWeekIndex > 0 ? Array(firstDayInWeekIndex).fill({}) : [];//存放日历上每周的日期集合
for(let day = 1; day <= lastDay; day++ ) {
if(weekDays.length === 7) {//数组长度满7后(每周7日)进行push和置空
daysCal.push(weekDays);
weekDays = [];
}
weekDays.push({text: day, date: dayjs(date).set("date", day).format("YYYY-MM-DD")});//重要!!!塞入日数值
}
daysCal.push(weekDays);
return daysCal;
}
/**
* 配置日历顶部的“周”文字
* @param wk 日历顶部周文字,0:代表依次是周日~周六,1:代表依次是周一~周日
* @param lang 日历顶部周文字展示语言,cn(默认):中文,en:英文
* @return ["周一", "周二"]
* **/
export function WeekCalendar(wk = 1, lang = "cn") {
let weeks = wk === 1 ? [1, 2, 3, 4, 5, 6, 7] : [0, 1, 2, 3, 4, 5, 6];
return weeks.map(wkIndex => WEEK_TEXT[wkIndex][lang]);
}
/**
* 基于“基准日期”,获取其近n月的月份集合
* @param date 基准月份
* @param n 基于基准月份,获取往前近n月集合
* @return [基准月份yyyy-mm, ..., 基准月份-n yyyy-mm]
* **/
export function RecentMonths(date = new Date(), n = 6) {
let months = [];
for(let i = 0; i < n; i++) {
let month = dayjs(date).subtract(i, "month").format("YYYY-MM");
months.push(month);
}
return months;
}
/**
* 配置周数字对应的中文、英文内容
* **/
const WEEK_TEXT = {
1: { cn: "周一", en: "Mon" },
2: { cn: "周二", en: "Tue" },
3: { cn: "周三", en: "Wen" },
4: { cn: "周四", en: "Thu" },
5: { cn: "周五", en: "Fri" },
6: { cn: "周六", en: "Sat" },
7: { cn: "周日", en: "Sun" },
}
2、dayjs文件
看官网:
下载安装方式:[Day.js中文网](https://dayjs.fenxianglu.cn/)
或者看本人这一片博客介绍:
[前端实用插件-日期处理工具Day.js](https://blog.csdn.net/qq_38192105/article/details/134120409)
5、用到的图标ICON
都是从Icon阿里巴巴矢量库里下载的,海量免费icon供程序员挑选,非常实用的网站
iconfont-阿里巴巴矢量图标库
总结
学海无涯