项目中遇到进行日期选择的需求,直接平铺在页面上,如下图所示
<template>
<div class="date-calender">
<div class="header-title">
<i @click="preYear" class="el-icon-d-arrow-left"></i>
<i @click="preMon" class="el-icon-arrow-left"></i>
<a class="data-now-a">{{currentYear}}年{{currentMonth+1}}月</a>
<i @click="nextMon" class="el-icon-arrow-right"></i>
<i @click="nextYear" class="el-icon-d-arrow-right"></i>
</div>
<div class="flex-week">
<a class="a-week" v-for="(item,index1) in listXIngqi" :key="index1">{{ item }}</a>
</div>
<ul class="date">
<!-- 标记当前时间 -->
<!-- <li v-for="(item, index) in list" :key="index" @click="handerSelect(item)" class="riqili"
:class="[( Number(item.y+''+item.m+''+item.d) >= Number(starttime) && Number(endtime) >= Number(item.y+''+item.m+''+item.d) ||
item.y+''+item.m+''+item.d == starttime|| item.y+''+item.m+''+item.d == endtime ) ? 'activeSelect' : '',(item.y === year && item.m === month && item.d === day)?'current-day-cricle':'',item.isSign?'sign-select':'']">
<div class="day" :class="{'text-color': item.cur}">
{{item.d}}
<a :class="item.y+''+item.m+''+item.d"></a>
</div>
</li> -->
<!-- 不标记当前时间 -->
<li v-for="(item, index) in list" :key="index" @click="handerSelect(item)" class="riqili"
:class="[( Number(item.y+''+item.m+''+item.d) >= Number(starttime) && Number(endtime) >= Number(item.y+''+item.m+''+item.d) ||
item.y+''+item.m+''+item.d == starttime|| item.y+''+item.m+''+item.d == endtime ) ? 'current-day-cricle' : '',item.isSign?'sign-select':'',(item.y === year && item.m === month && item.d === day)?'sign-quick' : '']">
<div class="day" :class="{'text-color': item.cur}">
{{item.d}}
<a :class="item.y+''+item.m+''+item.d"></a>
</div>
</li>
<li class="bg-month">{{currentMonth+1}}</li>
<li @click="getCurrentDate" class="quick-day-btn">今天</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
// year: new Date().getFullYear(), // 今日年份
// month: new Date().getMonth() + 1, // 今日月份
// day: new Date().getDate() > 9 ? new Date().getDate() : `0${new Date().getDate()}`, // 今日日份
year: '', // 今日年份
month: '', // 今日月份
day: '', // 今日日份
isQuick: false, //是否快捷今日
currentYear: '', // 当前显示年份
currentMonth: '', // 当前显示月份 0-11,显示时加一
currentDay: '', // 当前显示日份
monthDays: [], // 1-12月的天数
list: [],
listXIngqi: ['日', '一', '二', '三', '四', '五', '六'],
// listXIngqi: ['一', '二', '三', '四', '五', '六', '日'],
selectCompare: [],
clickcount: 0, //点击次数
starttime: '', //点击的开始的日期
endtime: '', //点击的结束时间 数字
params_starttime: '', //抛出去的参数
params_endtime: '' //抛出去的参数
};
},
props: {
isSingleChoice: {
type: Boolean,
default: true
},
signArr: {
type: Array,
default: () => []
}
},
mounted() {
this.showCalender();
},
methods: {
// 点击的日期
handerSelect(mess) {
if (mess.cur) {
// 清除快捷标记
if (!mess.isToQuick) {
this.year = ''; // 今日年份
this.month = ''; // 今日月份
this.day = '';
}
// 点击的是当前月
this.clickcount++;
if (this.isSingleChoice) {
this.starttime = mess.y + '' + mess.m + '' + mess.d;
let activeDate = this.$Tool.formate(`${mess.y}/${mess.m}/${mess.d}`, 'yyyy-MM-dd');
this.$emit('change', activeDate);
} else {
// 选择时间段
if (this.clickcount % 2 == 1) {
// 开始时间
this.starttime = mess.y + '' + mess.m + '' + mess.d;
this.endtime = '';
this.params_starttime =
mess.y +
'-' +
(mess.m > 9 ? mess.m : '0' + mess.m) +
'-' +
(mess.d > 9 ? mess.d : '0' + mess.d);
this.params_endtime = '';
} else {
// 结束时间
this.endtime = mess.y + '' + mess.m + '' + mess.d;
this.params_endtime =
mess.y +
'-' +
(mess.m > 9 ? mess.m : '0' + mess.m) +
'-' +
(mess.d > 9 ? mess.d : '0' + mess.d);
if (Number(this.starttime) > Number(this.endtime)) {
this.endtime = Number(this.starttime);
this.params_endtime = this.params_starttime;
this.starttime = Number(mess.y + '' + mess.m + '' + mess.d);
this.params_starttime =
mess.y +
'-' +
(mess.m > 9 ? mess.m : '0' + mess.m) +
'-' +
(mess.d > 9 ? mess.d : '0' + mess.d);
}
}
this.$emit('change', [this.params_starttime, this.params_endtime]);
}
} else {
// if(mess.d>20){
// this.nextMon();
// }else{
// this.preMon();
// }
}
},
isLeap(year) {
// 判断是不是闰年
return year % 100 === 0 ? (year % 400 === 0 ? 1 : 0) : year % 4 === 0 ? 1 : 0;
},
showCalender(type) {
console.log(type);
this.list = [];
this.newDate = new Date();
if (!type) this.currentYear = this.newDate.getFullYear();
if (!type) this.currentMonth = this.newDate.getMonth();
this.monthDays = [
31,
28 + this.isLeap(this.currentYear),
31,
30,
31,
30,
31,
31,
30,
31,
30,
31
];
this.currentDay = this.newDate.getDate();
this.firstDay = new Date(`${this.currentYear}-${this.currentMonth + 1}-1`);
this.firstnow = this.firstDay.getDay(); // 当月第一日是星期几 1-7
// if (this.firstnow === 0) this.firstnow = 7; //一周从周一开始的写法
// 从周一开始判断this.firstnow > 1 减去等于的情况
if (this.firstnow >= 1) {
// 前一个月份
let monIndex = this.currentMonth;
let year;
if (monIndex === 0) {
year--;
monIndex = 11;
} else {
monIndex--;
}
//一周从周一开始的写法
// for (let i = 0; i < this.firstnow - 1; i++) {
// this.list.unshift({
// y: year,
// m: monIndex + 1,
// d: this.monthDays[monIndex] - i
// });
// }
for (let i = 0; i < this.firstnow; i++) {
this.list.unshift({
y: year,
m: monIndex + 1,
d: this.monthDays[monIndex] - i
});
}
}
for (let i = 0; i < this.monthDays[this.currentMonth]; i++) {
// 标记当天时间
let dateF = `${this.currentYear}/${this.currentMonth + 1>9?this.currentMonth + 1:`0${this.currentMonth + 1}`}/${i + 1 > 9 ? i + 1 : `0${i + 1}`}`;
let dateSignF = this.signArr.filter((df) => {
let dfFormate = this.$Tool.formate(df, 'yyyy/MM/dd');
return dfFormate == dateF;
});
// 当前月份
this.list.push({
y: this.currentYear,
m: this.currentMonth + 1,
d: i + 1 > 9 ? i + 1 : `0${i + 1}`,
cur: true,
isSign: dateSignF.length > 0 ? true : false
});
}
//一周从周一开始的写法
// const num = (this.monthDays[this.currentMonth] + this.firstnow - 1) % 7;
const num = (this.monthDays[this.currentMonth] + this.firstnow) % 7;
// 从周一开始判断num > 0 减去等于的情况
if (num >= 0) {
// 下个月份
let monIndex2 = this.currentMonth;
let year2;
if (monIndex2 === 11) {
year2++;
monIndex2 = 0;
} else {
monIndex2++;
}
if (num > 0) {
for (let i = 0; i < 7 - num; i++) {
this.list.push({
y: year2,
m: monIndex2 + 1,
d: i + 1
});
}
}
}
},
clearData() {
this.clickcount = 0;
this.starttime = '';
this.endtime = '';
this.params_starttime = '';
this.params_endtime = '';
},
// 上个月
preMon() {
this.clearData();
if (this.currentMonth === 0) {
this.currentYear--;
this.currentMonth = 11;
} else {
this.currentMonth--;
}
this.showCalender('pre');
},
// 下个月
nextMon() {
this.clearData();
if (this.currentMonth === 11) {
this.currentYear++;
this.currentMonth = 0;
} else {
this.currentMonth++;
}
this.showCalender('next');
},
// 上一年
preYear() {
this.clearData();
this.currentYear--;
this.showCalender('pre');
},
// 下一年
nextYear() {
this.clearData();
this.currentYear++;
this.showCalender('next');
},
// 今日
getCurrentDate() {
let _date = {
cur: true,
d: new Date().getDate(),
isSign: true,
m: new Date().getMonth() + 1,
y: new Date().getFullYear(),
isToQuick: true
};
this.year = new Date().getFullYear(); // 今日年份
this.month = new Date().getMonth() + 1; // 今日月份
this.day = new Date().getDate() > 9 ? new Date().getDate() : `0${new Date().getDate()}`; // 今日日份
this.handerSelect(_date);
}
}
};
</script>
<style lang="scss" scoped>
@import '@/assets/css/travel-mixin.scss';
.date-calender {
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
.header-title {
width: 220px;
height: 40px;
opacity: 1;
// background: #f8f8f7;
display: flex;
justify-content: center;
align-items: center;
justify-content: space-between;
padding: 0 10px;
margin-top: 40px;
margin-bottom: 17px;
border-bottom: 1px solid $brdededed;
i {
font-size: 12px;
color: rgba(0, 0, 0, 0.45);
cursor: pointer;
}
.data-now-a {
font-size: 15px;
font-family: Helvetica, Helvetica-Regular;
font-weight: 400;
color: rgba(0, 0, 0, 0.85);
width: 100 px;
text-align: center;
font-size: 14px;
font-weight: 500;
}
}
.flex-week {
display: flex;
justify-content: space-between;
width: 210px;
.a-week {
font-size: 0;
font-size: 14px;
font-family: Helvetica, Helvetica-Regular;
font-weight: 400;
text-align: center;
color: #253f50;
display: inline-block;
width: 30px;
height: 30px;
}
}
.date {
position: relative;
display: flex;
justify-content: flex-start;
align-content: flex-start;
flex-wrap: wrap;
align-items: center;
width: 210px;
height: 180px;
.riqili {
// height: 28px;
// width: 28px;
// border: 1px solid transparent;
width: 30px;
height: 30px;
display: flex;
// 末尾或者上月天数颜色
justify-content: center;
align-items: center;
color: $cdisabled;
font-size: 14px;
position: relative;
z-index: 0;
//当前月的正常颜色
.text-color {
// font-size: 0;
font-size: 14px;
font-family: Helvetica, Helvetica-Regular;
font-weight: 400;
text-align: center;
color: #595959;
}
}
.riqili:nth-child(7n) {
margin-right: 0px;
}
}
.activeSelect {
width: 28px;
height: 28px;
opacity: 1;
border: 1px solid $comain !important;
border-radius: 50%;
.day {
color: $comain !important;
}
}
// 标识日期
.sign-select {
width: 28px;
height: 28px;
opacity: 1;
background: $cdate-status;
border: 1px solid $cdate-status !important;
border-radius: 50%;
.day {
color: $c6 !important;
}
}
// 背景月份
.bg-month {
width: 120px;
position: absolute;
top: 0px;
left: 50%;
margin-left: -60px;
font-size: 100px;
color: $cbgmain;
z-index: -1;
cursor: pointer;
text-align: center;
}
// 当天快捷键
.quick-day-btn {
position: absolute;
bottom: -50px;
width: 100%;
height: 40px;
line-height: 40px;
margin-top: 30px;
text-align: center;
border: 1px solid $comain;
border-radius: 4px;
background: $cbgmain;
color: $comain;
cursor: pointer;
}
// 当月当天的标识
.current-day-cricle,
.sign-quick {
display: block;
width: 30px;
height: 30px;
background: $comain;
border-radius: 50%;
position: absolute;
bottom: 0px;
left: 0px;
color: $cf;
z-index: -1;
.text-color {
color: $cf !important;
}
}
}
</style>