需求:
1.需要实现图片的代码基本效果
2.只能选择当前日期开始向后推5天,到当前日期的下俩个月,打个比方今天5.16号,选择的范围只能是5.21-6.16号。
废话不多说上代码:
template:
<template>
<div class="timepicker">
<div class="timepicker-box">
<div class="box-section">
<div class="section-slider">
<div class="slider-year-month">
<span class="year">{{queryYear}}</span>
<span class="month">{{queryMonth}}</span>
<i class="iconfont pre" @click="getPreMonthDayList"><</i>
<i class="iconfont next" @click="getNextMonthDayList">></i>
</div>
<div class="slider-week">
<span class="week-item" :key="key" v-for="(item, key) in weekList">{{item.name}}</span>
</div>
<div class="slider-day">
<div class="day-item"
:class="{'day-item-current': item._d.getDate() === activeDay.day && item._d.getMonth() + 1 === activeDay.month && item._d.getFullYear() === activeDay.year,'not-current-month':!item.current}"
:key="key" v-for="(item, key) in activeDayList"
@click="item.current ? drawCalendar(item._d) : ''">
<span>{{item._d.getDate()}}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
js:
<script>
export default {
name: "timepicker",
data() {
return {
// 星期数组
weekList: [
{name: "日"},
{name: "一"},
{name: "二"},
{name: "三"},
{name: "四"},
{name: "五"},
{name: "六"}
],
//正在渲染的日历
activeDayList: [],
//选取的日期
activeDay: new Object(),
//相对正在选取的日期的月前进数
step: 0,
queryYear: null,
queryMonth: null,
};
},
computed: {},
created() {
this.$getUserToken()
this.queryYear = new Date().getFullYear();
this.queryMonth = new Date().getMonth() + 1;
//最小选择日期
let min = new Date();
min.setTime(min.getTime() + 3600 * 1000 * 24 * 5);
this.drawCalendar(min);
},
methods: {
//计算一个月的天数
calDayGenerator(year, month) {
const actualMonth = month - 1;
const timeDistance =
+new Date(year, month) - +new Date(year, actualMonth);
return timeDistance / (1000 * 60 * 60 * 24);
},
//计算某年某某日星期几
calWeekGenerator(year, month, day) {
const actualMonth = month - 1;
let date = new Date();
date.setFullYear(year);
date.setMonth(actualMonth);
date.setDate(day);
return date.getDay();
},
// 获取前一个月日历
getPreMonthDayList() {
this.activeDayList = [];
this.step = this.step - 1;
let queryYear =
this.activeDay.month + this.step > 0
? this.activeDay.year
: this.activeDay.year -
(parseInt(Math.abs(this.activeDay.month + this.step) / 12) + 1);
let queryMonth =
this.activeDay.month + this.step > 0
? this.activeDay.month + this.step
: 12 - Math.abs(this.activeDay.month + this.step) % 12;
this.queryYear = queryYear;
this.queryMonth = queryMonth;
this.drawDayList(queryYear, queryMonth);
},
// 获取下个月日历
getNextMonthDayList() {
this.activeDayList = [];
this.step = this.step + 1;
let queryYear =
this.activeDay.month + this.step < 13
? this.activeDay.year
: (this.activeDay.month + this.step) % 12 === 0
? this.activeDay.year +
parseInt((this.activeDay.month + this.step) / 12) -
1
: this.activeDay.year +
parseInt((this.activeDay.month + this.step) / 12);
let queryMonth =
this.activeDay.month + this.step < 13
? this.activeDay.month + this.step
: (this.activeDay.month + this.step) % 12 === 0
? 12
: (this.activeDay.month + this.step) % 12;
this.queryYear = queryYear;
this.queryMonth = queryMonth;
this.drawDayList(queryYear, queryMonth);
},
// 绘制日历
drawCalendar(d) {
let currentYear = d.getFullYear(),
currentMonth = d.getMonth() + 1,
currentDay = d.getDate(),
currentWeek;
this.step = 0;
//转换周一到周日
switch (d.getDay()) {
case 0:
currentWeek = "周日";
break;
case 1:
currentWeek = "周一";
break;
case 2:
currentWeek = "周二";
break;
case 3:
currentWeek = "周三";
break;
case 4:
currentWeek = "周四";
break;
case 5:
currentWeek = "周五";
break;
case 6:
currentWeek = "周六";
break;
default:
break;
}
this.activeDay = {
_d: d,
year: currentYear,
month: currentMonth,
week: currentWeek,
day: currentDay
};
this.drawDayList(currentYear, currentMonth);
console.log('this.activeDay ==>', this.activeDay);
console.log('d ==>', d)
//传递点击的值
this.$emit("handlerSelect", d);
},
//绘制日期
drawDayList(year, month) {
this.activeDayList = this.combineDayListGenerator(year, month);
for (let item of this.activeDayList) {
//最小选择日期
let min = new Date();
min.setTime(min.getTime() + 3600 * 1000 * 24 * 4);
if (item._d < min) {
item.current = false
}
//最大选择日期
let max = new Date();
max.setMonth(max.getMonth() + 1);
if (item._d > max) {
item.current = false
}
}
console.log('this.activeDayList ==>', this.activeDayList);
},
//将上个月当前月和下个月的时间对象合并
combineDayListGenerator(year, month) {
const pre = this.preDayListGenerator(year, month);
const current = this.dayListGenerator(year, month);
const next = this.nextDayListGenerator(year, month);
const total = pre.concat(current).concat(next);
console.log('pre ==>', pre);
console.log('current ==>', current);
console.log('next ==>', next);
console.log('total ==>', total);
return total;
},
//生成某年月缺少前一个月的时间对象数组
preDayListGenerator(year, month) {
let preDayNum, preSurplusDayNum, actualPreMonth;
if (month === 1) {
preDayNum = this.calDayGenerator(year - 1, 12);
preSurplusDayNum = this.calWeekGenerator(year, month, 1);
actualPreMonth = month - 2;
} else {
preDayNum = this.calDayGenerator(year, month - 1);
preSurplusDayNum = this.calWeekGenerator(year, month, 1);
actualPreMonth = month - 2;
}
let preDayList = new Array();
for (let i = 1; i < preDayNum + 1; i++) {
let currentDay = {
_d: new Date(year, actualPreMonth, i),
current: false
};
preDayList.push(currentDay);
}
return preSurplusDayNum === 0 ? [] : preDayList.slice(-preSurplusDayNum);
},
// 生成某年月天数日期对象数组
dayListGenerator(year, month) {
const dayNum = this.calDayGenerator(year, month);
const actualMonth = month - 1;
let dayList = new Array();
for (let i = 1; i < dayNum + 1; i++) {
let currentDay = {
_d: new Date(year, actualMonth, i),
current: true
};
dayList.push(currentDay);
}
return dayList;
},
// 生成某年月应该添加后一个月的时间对象数组
nextDayListGenerator(year, month) {
const preSurplusDayNum = this.calWeekGenerator(year, month, 1);
const dayNum = this.calDayGenerator(year, month);
const NextDayNum = this.calDayGenerator(year, month + 1);
const NextSurplusDayNum = 7 * 6 - (preSurplusDayNum + dayNum);
const actualNextMonth = month;
let nextDayList = new Array();
for (let i = 1; i < NextDayNum + 1; i++) {
let currentDay = {
_d: new Date(year, actualNextMonth, i),
current: false
};
nextDayList.push(currentDay);
}
return nextDayList.slice(0, NextSurplusDayNum);
},
}
};
</script>
css:
<style lang="less" scoped>
.timepicker {
position: fixed;
top: 0px;
right: 0px;
bottom: 0px;
left: 0px;
background-color: rgba(0, 0, 0, 0.5);
z-index: 99;
.timepicker-box {
position: absolute;
display: flex;
flex-direction: column;
top: 50%;
left: 50%;
width: 75%;
height: 39%;
transform: translate(-50%, -50%);
background: #fff;
z-index: 100;
.box-header {
box-sizing: border-box;
flex-basis: 22%;
display: flex;
flex-direction: column;
padding: 10px 10px;
background: #0169b6;
.header-year {
flex-basis: 30%;
display: flex;
align-items: center;
overflow-y: hidden;
span {
flex: 1;
font-size: 14px;
color: #fff;
}
}
.header-month-date {
flex-grow: 2;
display: flex;
align-items: center;
overflow-y: hidden;
span {
flex-grow: 0;
font-size: 25px;
color: #fff;
padding: 0px 3px;
}
.month {
&::after {
content: "月";
}
}
.day {
&::after {
content: "日";
}
}
}
}
.box-section {
position: relative;
flex: 1;
.section-slider {
position: absolute;
display: flex;
flex-direction: column;
top: 0px;
left: 0px;
bottom: 0px;
right: 0px;
padding: 10px 15px;
.slider-year-month {
position: relative;
flex-basis: 10%;
display: flex;
align-items: center;
justify-content: center;
span {
flex: 0;
font-size: 14px;
font-weight: 600;
}
.year {
&::after {
content: "年";
}
}
.month {
&::after {
content: "月";
}
}
i {
font-size: 16px;
}
.pre {
position: absolute;
top: 50%;
left: 0%;
transform: translateY(-50%);
}
.next {
position: absolute;
top: 50%;
right: 0%;
transform: translateY(-50%);
}
}
.slider-week {
flex-basis: 10%;
display: flex;
align-items: center;
.week-item {
flex: 1;
font-size: 14px;
text-align: center;
}
}
.slider-day {
flex: 1;
display: flex;
flex-wrap: wrap;
.day-item {
flex-basis: 14.285%;
display: flex;
align-items: center;
justify-content: center;
span {
flex: 1;
text-align: center;
font-size: 14px;
}
}
.day-item-current {
span {
border-radius: 100%;
color: #fff;
background: #5caeff;
}
}
.not-current-month {
span {
color: gray;
}
}
}
}
}
.box-footer {
flex-basis: 10%;
display: flex;
box-shadow: 0px -1px 0px #eee;
.footer-btn {
flex: 1;
text-align: center;
span {
font-size: 16px;
}
&:not(:last-child) {
box-shadow: 1px 0px 0px #eee;
}
}
}
}
}
</style>
有需要的,可以到我的GitHub拉取源代码,需要留言即可