工作笔记:写一个时间以日历的方式选着日期
直接上代码,复制做成组件便可使用。
<template>
<div>
<header class="header">
{{dateStart.substring(0,4) + '年' + dateStart.substring(5,7)+'月'}}
</header>
<div class="body">
<div class='calendar'>
<div class='week-title'>
<div>日</div>
<div>一</div>
<div>二</div>
<div>三</div>
<div>四</div>
<div>五</div>
<div>六</div>
</div>
<div class='box' style="display: flex;">
<div class='calendar-body'>
<div v-for="(item,index) in calendar" :key="index">
<div class='calendar-data'>
<div class="day"
:class="item2.disabled + ' '+ item2.disabled2 + ' ' +item2.start_date + ' ' + item2.end_date +' ' + item2.active_date"
v-for="(item2,index) in item.days"
:key="index"
@click="selectDate(item2)">
{{item2.day}}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<footer>
<div class="screenbottom">
<el-button type="primary" @click="empty">清 空</el-button>
<el-button type="success" @click="determine">确 定</el-button>
</div>
</footer>
</div>
</template>
<script>
export default {
data(){
return {
start:'',
calendar:[],
month_length: 6,
max_reserve_days: 0,
max_reserve_date: '',
select_start_ymd : '',
select_start_show: '',
select_end_ymd: '',
select_end_show: '',
select_index:'start',
select_all_day:'',
dateStart:"2022-05-01 14:33:40"
}
},
created(){
this.initDate()
},
methods:{
/**
* @author { Paraboy }
* @methodName { determine }
* 描述: 确定选着时间
* @param { }
* @return { }
*/
determine(){
console.log('开始时间',this.select_start_ymd)
console.log('结束时间',this.select_end_ymd)
},
/**
* @author { Paraboy }
* @methodName { empty }
* 描述: 清空已选着的时间
* @param { }
* @return { }
*/
empty:function() {
this.calendar[0].days.map((item) => {
if(item.active_date || item.end_date ||item.start_date){
item.active_date = ''
item.end_date = ''
item.start_date = ''
}
this.dataTimeList = []
})
},
/**
* @author { Paraboy }
* @methodName { initDate }
* 描述: 初始化日期
* @param { }
* @return { }
*/
initDate:function(){
var _this = this;
// 创建时间对象
this.calendar = []
let date = new Date();
// 获取完整年月
let fullDate = [
date.getFullYear(),
date.getMonth()+1,
date.getDate(),
`${date.getFullYear()}-${date.getMonth()+1}-${date.getDate()}`
];
/**
* 从缓存拿已经设置的开始和结束日期
* 如果第一次用户是第一次进入。则设置默认值为,并且保存进缓存。
*/
var select_start_ymd = '';
var select_start_ymd_show = '';
var select_end_ymd = '';
var select_end_ymd_show = '';
if (select_start_ymd == '' || select_start_ymd == undefined || select_start_ymd == 'undefined' || _this.compareDate(select_start_ymd, fullDate[3]) == 3) {
select_start_ymd = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate();
select_start_ymd_show = _this.parseMonth(date.getMonth() + 1) + '月' + _this.parseDay(date.getDate()) + '日';
}
if (select_end_ymd == '' || select_end_ymd == undefined || select_end_ymd == 'undefined' || _this.compareDate(select_end_ymd, fullDate[3]) == 3) {
let temp_date = new Date(date.getTime() + 86400 * 1000)
select_end_ymd = temp_date.getFullYear() + '-' + (temp_date.getMonth() + 1) + '-' + temp_date.getDate();
select_end_ymd_show = _this.parseMonth(temp_date.getMonth() + 1) + '月' + _this.parseDay(temp_date.getDate()) + '日';
}
//设置数据。并且保存缓存
_this.select_start_ymd = select_start_ymd
_this.select_end_ymd = select_end_ymd
//通过月份。计划最长可预定天数和日期 ,最后一天为离店时间。所以多加一天可选择
let max_reserve_days = _this.month_length * 30 + 1;
//最大天数转换成毫秒数。再转换成时间
let max_date = new Date(date.getTime() + max_reserve_days * 24 * 60 * 60 * 1000);
let max_reserve_date = max_date.getFullYear() + '-' + (max_date.getMonth() + 1) + '-' + max_date.getDate() + '';
_this.max_reserve_days = max_reserve_days
_this.max_reserve_date = max_reserve_date
//获取当前月份完整日期天数
let cur_month_date = new Date(fullDate[0] + '-' + _this.parseMonth(fullDate[1]) + '-01')
let cur_month = {};
cur_month.fullYear = fullDate[0]; // 年
cur_month.fullMonth = fullDate[1]; //月
cur_month.dayLength = _this.getMonthDays(cur_month.fullMonth, cur_month.fullYear);//当前月份总共有多少天
cur_month.firstDayWeek = cur_month_date.getDay(); //当前月份第一天星期几0~7
cur_month.curDay = date.getDate(); //当前天
cur_month.days = [];
//初始化天数
var item = {};
for (let i = 1; i <= cur_month.dayLength; i++) {
item = {
ymd: cur_month.fullYear + '-' + _this.parseDay(cur_month.fullMonth) + '-' + _this.parseDay(i),
ymd_cn: _this.parseMonth(cur_month.fullMonth) + '月' + _this.parseDay(i) + '日',
day: i,
disabled: i < cur_month.curDay ? '' : '',
};
//开始时间
item.start_date = _this.compareDate(_this.select_start_ymd, item.ymd) == 2 ? '' : '';
//中间的日期
item.active_date = (_this.compareDate(_this.select_start_ymd, item.ymd) == 3 && _this.compareDate(_this.select_end_ymd, item.ymd) == 1) ? 'active' : '';
//结束时间
item.end_date = _this.compareDate(_this.select_end_ymd, item.ymd) == 2 ? '' : '';
//超过设置最长日期。禁止选择
item.disabled2 = _this.compareDate(max_reserve_date, item.ymd) == 3 ? '' : '';
cur_month['days'].push(item);
}
//前补0
if (cur_month.firstDayWeek > 0) {
for (let i = 0; i < cur_month.firstDayWeek; i++) {
cur_month['days'].unshift('');
}
}
_this.calendar.push(cur_month)
var next_month_date;
var nextfullDate = [];
},
/**
* @author { Paraboy }
* @methodName { parseMonth }
* 描述: 格式月份期
* @param { month }
* @return { month }
*/
parseMonth: function(month){
month = parseInt(month);
if(month <10){
month = '0'+month
}
return month;
},
/**
* @author { Paraboy }
* @methodName { parseDay }
* 描述: 格式天数
* @param { day }
* @return { day }
*/
parseDay: function (day) {
day = parseInt(day);
if (day < 10) {
day = '0' + day
}
return day;
},
/**
* @author { Paraboy }
* @methodName { getMonthDays }
* 描述: 获取每个月的天数
* @param { month,year }
* @return { number }
*/
getMonthDays(m, year) {
let days = [0, 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
if (m != 2) {
return days[m];
}
if ((year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0 && year % 100 === 0)) {
return 29
} else {
return 28
}
},
compareDate(date1, date2){
var dateone = date1.replace(/-/g,'/');
var datetwo = date2.replace(/-/g,'/');
var oDate1 = new Date(dateone)
var oDate2 = new Date(datetwo)
if(oDate1.getTime() > oDate2.getTime()){
return 1; //大于
} else if (oDate1.getTime() == oDate2.getTime()) {
return 2; //等于
}else{
return 3; //小于
}
},
/**
* @author { Paraboy }
* @methodName { selectDate }
* 描述: 点击日期按钮
* @param { item }
* @return { }
*/
selectDate:function(item){
var _this = this;
let select_data = item;
let select_start_ymd = _this.select_start_ymd;
let select_end_ymd = _this.select_end_ymd;
//如果是点击不能用的地址
if (select_data.disabled != ''){
return false;
}
if (_this.select_index == 'start') {
select_start_ymd = select_data.ymd;
//如果选择的日期。是当前日期。或者比当前开始日期还早的。就 要把当前日期变为开始日期
_this.select_start_ymd = select_start_ymd;
_this.select_start_ymd_show = select_data.ymd_cn;
_this.select_end_ymd = '';
_this.select_end_ymd_show = '';
//将索引改为结束时间
_this.select_index = 'end';
} else if (_this.select_index == 'end'){
let v = _this.compareDate(select_start_ymd, select_data.ymd)
//如果选择的时间大于开始时间。则有效。否则重置开始时间
if(v == 3 ){
_this.select_end_ymd = select_data.ymd;
_this.select_end_ymd_show = select_data.ymd_cn;
//将索引改为结束时间
_this.select_index = 'start';
//保存数据到缓存
_this.saveDate();
}else{
_this.select_start_ymd = select_data.ymd;
_this.select_start_ymd_show = select_data.ymd_cn;
_this.select_end_ymd = '';
_this.select_end_ymd_show = '';
//将索引改为结束时间
_this.select_index = 'end';
}
}
_this.resetCalendar();
},
//重新计算一下日历
resetCalendar:function(){
let _this = this;
let calendar = _this.calendar;
if(calendar.length > 0 ){
for (var i in calendar){
if(calendar[i]['days'].length > 0 ){
for (var i2 in calendar[i]['days']) {
if (calendar[i]['days'][i2] != ''){
//开始时间
calendar[i]['days'][i2]['start_date'] = _this.compareDate(_this.select_start_ymd, calendar[i]['days'][i2]['ymd']) == 2 ? 'active-start' : '';
//中间的日期
calendar[i]['days'][i2]['active_date'] = (_this.compareDate(_this.select_start_ymd, calendar[i]['days'][i2]['ymd']) == 3 && _this.compareDate(_this.select_end_ymd, calendar[i]['days'][i2]['ymd']) == 1) ? 'active' : '';
//结束时间
calendar[i]['days'][i2]['end_date'] = _this.compareDate(_this.select_end_ymd, calendar[i]['days'][i2]['ymd']) == 2 ? 'active-end' : '';
}
}
}
}
}
_this.calendar = calendar;
},
//如果设置结束时间成功。保存一次当前时间。并且计算总天数。到缓存中
saveDate:function(){
var _this = this;
var date1 = new Date(this.select_start_ymd.replace(/-/g,'/'));
var date2 = new Date(this.select_end_ymd.replace(/-/g,'/'));
//计算天数
var days = parseInt((date2.getTime() - date1.getTime()) / 1000 / 86400);
//保存缓存
_this.select_all_day = days;
console.log(_this.select_all_day)
}
},
}
</script>
<style scoped>
.header{
width:100%;
height:40px;
text-align: center;
position: relative;
line-height: 40px;
}
.golbal-left{
width: 13px;
height: 13px;
border-top: 2px solid gainsboro;
border-right: 2px solid gainsboro;
transform: rotate(225deg);
-webkit-transform: rotate(225deg);
position: absolute;
left: 16px;
top: 15px;
}
.calendar {
width: 100%;
/* justify-content: space-between;
display: flex; */
/* border: 1px solid red; */
}
.calendar-body{
width: 100%;
}
.week-title {
width: 100%;
justify-content: space-between;
display: flex;
text-align: center;
}
.week-title>div {
flex: 1;
/* width: 14.28vw; */
height: 2rem;
line-height: 2rem;
float: left;
}
.calendar-data {
width: 100%;
clear: both;
/* display: flex; */
}
.calendar-data>div {
width: 14.28%;
height: 50px;
float: left;
text-align: center;
line-height: 50px
}
.day.disabled{
color:#ddd;
}
.active-start {
color: white;
background-color: #30b6af;
}
.active-start::after {
content: '开始';
font-size: .5rem;
}
.active {
color: white;
background-color: rgba(63,182,175,.5);
}
.active-end {
color: white;
background-color: #30b6af;
position: relative;
}
.active-end::after {
content: '结束';
font-size: .5rem;
}
.active-end i{
position: absolute;
top:-120%;
width:100%;
height:100%;
background:rgba(0,0,0,1);
opacity:0.6;
border-radius:8px;
display: flex;
align-items: center;
justify-content: center;
font-style: normal;
font-size: 15px;
color:#fff;
}
.active-end i::after{
position: absolute;
content: '';
float: left;
width: 0;
height: 0;
border-width: 10px;
border-style: solid;
border-color:#000 transparent transparent transparent;
opacity:1;
bottom:-20px;
left:50%;
margin-left:-10px;
}
.screenbottom{
height:35px;
width:100%;
display: flex;
justify-content: space-between;
margin-top: 20px;
}
.reset{
width:50%;
height:40px;
line-height: 40px;
color:#3E3E3E;
text-align: center;
background: #fff;
}
.determine{
width:50%;
height:40px;
line-height: 40px;
background: #48D8BF;
color:#fff;
text-align: center;
}
footer{
width:100%;
}
</style>