moment
moment是一个js工具库,这个库中封装的是日期时间的方法,功能很全面。可以去moment官网看看,它的中文文档介绍的也很详细,主要是看一下方法的使用。附上官网地址:添加链接描述
日历案例
日历的逻辑:
从当前月出发,必须直到当前月的天数,必须知道当前月第一天是星期几。
只有知道了天数和第一天是星期几,才能知道第一天的位置在哪,要显示几天
案例中需要使用的方法:
以下方法都是在moment()返回对象身上的方法
获取当前日期和时间:moment()
获取某月的天数:daysInMonth()
获取某月的第一天:startOf(‘month’)
获取某天是星期几:weekday()
增加时间:add(Number, String)
减去时间:subtract(Number, String)
设置一周从周一开始(默认是周日开始):locale(‘zh-cn’)
显示格式:format()。这个是使用最多用处最大的方法,它的参数是令牌,令牌不同日期和时间显示不同。
我们来看下效果:
代码:
<template>
<div class="public-box" v-else>
<p>{{ titleVal }}</p>
<ul class="week-title flex">
<li v-for="(v, i) in weekList" :key="i">{{ v }}</li>
</ul>
<ul class="date-list flex" :class="index % 2 === 0 ? 'odd' : ''" v-for="(arr, index) in dateList" :key="index + 'a'">
<li :class="obj.class + ' ' + (i === arr.length - 1 ? '' : 'border-right')" v-for="(obj, i) in arr" :key="i">{{ obj.d }}</li>
</ul>
</div>
</template>
<script>
import moment from "moment";
// zh-cn默认一周从周一开始
// moment.locale('zh-cn');
export default {
name: "CalendarDate",
data() {
return {
weekList: ["日", "一", "二", "三", "四", "五", "六"],
titleVal: '2023-09',
dateList: []
};
},
mounted() {
this.setDate();
},
methods: {
setDate() {
let m = moment('2023-09-01');
// 获得当前月的天数 和 第一天的星期数
let curDays = this.getMonthDays(m); // 当前天数
let curWeek = this.getWeekDays(m.clone()); // 当前月第一天的星期(索引值)
let upDays = this.getMonthDays(m.clone().subtract(1, "month")); // 上月的天数
console.log(curWeek);
let currentM = moment(m).format("YYYY-MM"); // 当前月
let beforeM = moment(m).subtract(1, "months").format("YYYY-MM"); // 上个月
let afterM = moment(m).add(1, "months").format("YYYY-MM"); // 下个月
// 生成的结构
let strDate = [];
// 下个月的起始日期
let nextFirstDate = 0;
// 日历最多有 6行 6*7
let allNum = 42;
for (let i = 0; i < allNum; i++) {
// 1. 当前月的上一个月 需要显示的日期
// 返回的索引值刚好是上月在当月显示的天数
if (i < curWeek) {
strDate.unshift({
class: "special",
d: upDays,
m: beforeM
});
upDays--; // 倒叙显示 30 31
} else if (i >= curDays + curWeek) {
// 去除掉当月天数+上月天数就是下月天数
// 2. 当前月的下一个月:除去当月最后一天+上月的几天剩余的是下月开始计算
// curWeek 返回值刚好是上月占用的天数
nextFirstDate++;
strDate.push({
class: "special",
d: nextFirstDate,
m: afterM
});
} else {
// 3. 当前月
// i-curWeek+1 为当前月的天数
// date()获取日期号
// m.date() == i - curWeek + 1说明这一天是当月当天,添加样式
let currentClass = moment().date() === i - curWeek + 1 ? "current-day" : "current";
strDate.push({
class: currentClass,
d: i - curWeek + 1,
m: currentM
});
}
}
// strDate
let times = allNum / 7;
let dateList = [];
for (let k = 0; k < times; k++) {
let arr = [];
for (let i = 0; i < 7; i++) {
arr.push(strDate[i + k * 7]);
}
dateList.push(arr);
}
if (dateList[times - 1][0]["m"] === afterM) {
dateList.pop();
}
this.dateList = dateList;
},
getWeekDays(momentObj) {
// 星期几,0-6, 星期天为0
// 或者用 .day() 效果一样
return momentObj.startOf("month").weekday();
},
getMonthDays(momentObj) {
return momentObj.daysInMonth();
}
}
};
</script>
<style lang="scss" scoped>
.public-box {
/*height: 290px;*/
padding: 20px;
border: 1px solid #dfdfdf;
> p {
color: #374256;
font-weight: 500;
text-align: center;
margin-bottom: 10px;
}
.week-title {
width: 100%;
/*margin-bottom: 10px;*/
/*border-bottom: 1px solid #dfdfdf;*/
li {
text-align: center;
line-height: 60px;
font-size: 12px;
flex: 1;
background-color: #EAECF3;
/*width: 30px;*/
/*margin: 0 8px;*/
}
}
.date-list {
width: 100%;
margin-bottom: 3px;
li {
text-align: center;
line-height: 80px;
color: #475369;
/*width: 30px;*/
flex: 1;
/*margin: 0 8px;*/
/*border-radius: 15px;*/
/*cursor: pointer;*/
}
.special {
color: #b1b8c5;
}
}
.odd {
background-color: #F5F7FD;
}
.border-right {
border-right: 1px solid #D9E1EB;
}
}
</style>