需求页面样式如下
代码可直接复制使用
<template>
<div>
<div class="calendar">
<div class="calendarHeader">
<div style="float: left" class="cursor" @click="goPreviousYear()">
<!-- <div class="lineleft"></div>
<div class="lineleft"></div> -->
<i class="el-icon-d-arrow-left"></i>
</div>
<i class="el-icon-arrow-left cursor" @click="goPreviousMonth()"></i>
<b style="margin: 0px 15px; display: inline-block; color: #333">
{{ currentMonth }}
</b>
<i class="el-icon-arrow-right cursor" @click="goNextMonth()"></i>
<div style="float: right" class="cursor" @click="goNextYear()">
<!-- <div class="lineright"></div>
<div class="lineright"></div> -->
<i class="el-icon-d-arrow-right"></i>
</div>
</div>
<div class="calendarMain">
<div class="calendarMainHeader">
<span v-for="(item, index) in weekDay" :key="index" class="weekItem">
{{ item.name }}
</span>
</div>
<div class="calendarMainBody">
<span
v-for="(item, index) in dateList"
:key="index"
class="dataItem cursor"
@click="handleClick(item, $event)"
>
<span
class="hoverStyle"
:class="[
{ color666: item.type !== 'current' },
{
checkStyle:
selectTime === `${item.year}-${item.month}-${item.day}`,
},
{ color666: disable },
{ color666: ableClick(item) },
]"
>{{ item.value }}</span
>
</span>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
time: {}, //(yyyy-mm) 当前显示月份(初始化一次 不做后期同步)
selectTime: {}, // (yyyy-mm-dd) 当前选中的日期(单向数据流)
disable: {
//是否禁止选择日期 (用于起始 结束日期的禁止联动)
type: Boolean,
default: false,
},
isdataCheck: {
//是否禁止某个日期以前的时间不可选(与CheckData参数搭配使用)
type: Boolean,
default: false,
},
CheckData: {
//yyyy-mm-dd)禁止某个日期以前的时间不可选的日期 (isdataCheck为true时生效)
type: String,
default: "",
},
},
data() {
return {
newTime: this.time,
selectValue: this.selectTime,
weekDay: [
{
name: "一",
code: "Monday",
},
{
name: "二",
code: "Tuesday",
},
{
name: "三",
code: "Wednesday",
},
{
name: "四",
code: "Thursday",
},
{
name: "五",
code: "Friday",
},
{
name: "六",
code: "Saturday",
},
{
name: "日",
code: "Sunday",
},
],
dateList: [],
};
},
computed: {
currentMonth() {
return `${this.newTime.split("-")[0]}年${this.newTime.split("-")[1]}月`;
},
},
methods: {
goPreviousYear() {
let a = this.newTime.split("-");
a[0] = a[0] - 1;
this.newTime = a.join("-");
this.dataListNew(this.newTime, this.newTime);
this.$emit("changeTime", this.newTime);
},
goNextYear() {
let a = this.newTime.split("-");
a[0] = a[0] * 1 + 1;
this.newTime = a.join("-");
this.dataListNew(this.newTime, this.newTime);
this.$emit("changeTime", this.newTime);
},
goPreviousMonth() {
this.newTime = this.previousMonth(this.newTime);
this.dataListNew(this.newTime, this.newTime);
this.$emit("changeTime", this.newTime);
},
goNextMonth() {
this.newTime = this.nextMonth(this.newTime);
this.dataListNew(this.newTime, this.newTime);
this.$emit("changeTime", this.newTime);
},
goNowTime() {
this.newTime = this.getTime();
this.dataListNew(this.newTime, this.newTime);
this.$emit("changeTime", this.newTime, "nowTime");
},
getTime() {
let today = new Date();
let year = today.getFullYear();
let month = today.getMonth() + 1;
let days = today.getDate();
let newTime = `${year}-${this.formateDate(month)}-${this.formateDate(
days
)}`;
return newTime;
},
formateDate(str) {
return str < 10 ? "0" + str : str;
},
// 生成当月长度数组
listNew(time, type) {
let x = time.split("-");
let a = new Date(x[0], x[1], 0).getDate();
let b = Array.from(new Array(a).keys());
let c = [];
b.forEach((item) => {
c.push({
value: item + 1,
type: type,
year: x[0],
month: x[1],
day: (item + 1 + "").padStart(2, "0"),
select: false,
});
});
return c;
},
// 计算上个月日期
previousMonth(time) {
let a = time.split("-");
if (a[1] == "01") {
a[0] = a[0] - 1;
a[1] = "12";
} else {
a[1] = (a[1] - 1 + "").padStart(2, "0");
}
return a.join("-");
},
// 计算下个月日期
nextMonth(time) {
let a = time.split("-");
if (a[1] == "12") {
a[0] = a[0] * 1 + 1;
a[1] = "01";
} else {
a[1] = (a[1] * 1 + 1 + "").padStart(2, "0");
}
return a.join("-");
},
// 汇总数据 生成日期数组
dataListNew(startTime, endTime) {
this.dateList = [];
// 开始时间
let a = startTime.split("-");
// 结束时间
let b = endTime.split("-");
// 上个月的日期
let c = this.previousMonth(startTime).split("-");
let d = this.listNew(this.previousMonth(startTime), "previous");
c[2] = d[d.length - 1].value;
let J = new Date(c.join("-")).getDay();
let k = [];
if (J !== 0) {
k = d.splice(J * -1);
}
// 下个月的日期
let e = this.nextMonth(endTime).split("-");
let f = this.listNew(this.nextMonth(endTime), "next");
e[2] = f[0].value;
let L = new Date(e.join("-")).getDay();
let G = [];
G = f.splice(0, 8 - L);
// 拼接上个月的数据
this.dateList = this.dateList.concat(k);
// 拼接当前月的数据
this.dateList = this.dateList.concat(
this.listNew(a.join("-"), "current")
);
// 拼接间隔月的数据
while (a.join("-") !== b.join("-")) {
if (a[1] == "12") {
a[0] = a[0] * 1 + 1;
a[1] = "01";
} else {
a[1] = (a[1] * 1 + 1 + "").padStart(2, "0");
}
// 拼接下个月的数据
this.dateList = this.dateList.concat(this.listNew(a.join("-")));
}
this.dateList = this.dateList.concat(G);
},
handleClick(item, e) {
if (e.target.className.indexOf("color666") > 0) {
return;
}
this.$emit("startDataHandle", `${item.year}-${item.month}-${item.day}`);
},
ableClick(item) {
if (this.isdataCheck) {
return (
Date.parse(new Date(`${item.year}-${item.month}-${item.day}`)) <
Date.parse(new Date(this.CheckData))
);
} else {
return false;
}
},
},
created() {
this.dataListNew(this.newTime, this.newTime);
},
watch: {
time: function (newValue) {
this.selectValue = newValue;
},
disable: function (newValue) {
//console.log(newValue);
},
},
};
</script>
<style scoped="scoped">
.calendar {
width: 285px;
height: 318px;
}
.calendarHeader {
width: 280px;
height: 50px;
line-height: 50px;
text-align: center;
padding: 0px 5px;
box-sizing: border-box;
}
.calendarMain {
width: 285px;
height: 268px;
box-sizing: border-box;
font-size: 14px;
}
.lineright {
width: 5px;
height: 5px;
transform: rotate(45deg);
display: inline-block;
border-top: 1px solid #000;
border-right: 1px solid #000;
}
.lineleft {
width: 5px;
height: 5px;
transform: rotate(-135deg);
display: inline-block;
border-top: 1px solid #000;
border-right: 1px solid #000;
}
.calendarMainHeader {
/* display: flex; */
background: #f0f8ff;
color: #1e9bff;
}
.weekItem {
display: inline-block;
width: calc(100% / 7 - 6px);
height: 34.85px;
line-height: 34.85px;
margin: 0px 3px;
text-align: center;
}
.calendarMainBody {
/* display: flex;
flex-wrap: wrap; */
}
.dataItem {
display: inline-block;
width: calc(100% / 7 - 6px);
height: 34.85px;
line-height: 34.85px;
margin: 0px 3px;
text-align: center;
}
.color666 {
color: #ccc;
cursor: not-allowed !important;
}
.cursor {
cursor: pointer;
}
.checkStyle {
border-radius: 50%;
background-color: #1e9bff;
color: white;
display: inline-block;
height: 25px;
width: 25px;
line-height: 25px;
}
.hoverStyle:hover {
border-radius: 50%;
background-color: #1e9bff;
color: white;
display: inline-block;
height: 25px;
width: 25px;
line-height: 25px;
}
</style>