vue自定义日期选择,类似美团日期选择,日历控件,vue日历区间选择
一个日历的控件,基于vue的,可以日历区间选择,可用于酒店日历区间筛选,动手能力强,可以修改成小程序版本的,先上效果图
里面的颜色样式都是可以修改的
选择范围效果
话不多说,直接上干货,代码可以直接复制访问
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no" />
<meta name="renderer" content="webkit">
<title></title>
</head>
<style>
html,body{padding:0;margin:0;height:100%;}
.header{
width:100%;
height:40px;
text-align: center;
position: relative;
line-height: 40px;
}
.body{
width: 100%;
height:87%;
height: -moz-calc(100% - 80px);
height: -webkit-calc(100% - 80px);
height: calc(100% - 80px);
overflow-y: auto;
position:absolute;
}
.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: 100vw;
text-align: center;
}
.week-title {
overflow: hidden;
position: fixed;
margin-bottom: 1.5rem;
background-color: #f6f6f8;
z-index: 2;
}
.week-title>div {
width: 14.28vw;
height: 2rem;
line-height: 2rem;
float: left;
}
.box {
position: absolute;
top: 2rem;
z-index: 1;
}
.data-title {
height: 2rem;
line-height: 2rem;
border-top: 1px solid #ededed;
border-bottom: 1px solid #ededed;
clear: both;
}
.calendar-data {
width: 100vw;
clear: both;
}
.day {
width: 14.28vw;
height: 3rem;
line-height: 1.6rem;
float: left;
display: flex;
flex-direction: column;
}
.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;
}
.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{
position: fixed;
bottom:0;
width:100%;
}
[v-cloak]
{
display: none;
}
</style>
<body>
<div id='app' v-cloak>
<header class="header">
<span>时间范围</span>
</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'>
<div class='calendar-body'>
<div v-for="(item,index) in calendar">
<!-- 标题 -->
<div class='data-title'>
{{item.fullYear + '年' + item.fullMonth+'月'}}
</div>
<!-- 日期 -->
<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"
@click="selectDate(item2)">
{{item2.day}}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<footer>
<div class="screenbottom">
<div class="reset">取消</div>
<div class="determine">确定</div>
</div>
</footer>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({
el:'#app',
data:{
start:'', //开始时间。从当天开始。
calendar:[],
month_length: 6, //最长预定多少个月后的房间 读取总店配置。
max_reserve_days: 0, //最长预定天数。,一个月按30天计划
max_reserve_date: '', //最长可预定的日期。例如:2019-09-12
select_start_ymd : '', //入住开始提交时间 例如:2019-5-8
select_start_show: '', //入住开始显示时间 例如:05月08日
select_end_ymd: '', //离店开始提交时间 例如:2019-5-8
select_end_show: '', //离店开始显示时间 例如:05月08日
select_index:'start', //记录当前点击时间,所对应的时间是开始时间还是结束时间
select_all_day:''
},
methods:{
initDate:function(){
var _this = this;
// 创建时间对象
let date = new Date();
//如果当前时间为凌晨6点前。则当前日期往前一天
if (date.getHours() < 6) {
date = new Date(date.getTime() - 86400 * 1000);
}
// 获取完整年月
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 + '-' + cur_month.fullMonth + '-' + i,
ymd_cn: _this.parseMonth(cur_month.fullMonth) + '月' + _this.parseDay(i) + '日',
day: i,
disabled: i < cur_month.curDay ? 'disabled' : '',
};
//开始时间
item.start_date = _this.compareDate(_this.select_start_ymd, item.ymd) == 2 ? 'active-start' : '';
//中间的日期
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 ? 'active-end' : '';
//超过设置最长日期。禁止选择
item.disabled2 = _this.compareDate(max_reserve_date, item.ymd) == 3 ? 'disabled' : '';
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 = [];
for (let i2 = 0; i2 < _this.month_length; i2++) {
//下一个朋的天数信息
next_month_date = new Date(fullDate[0], fullDate[1] + i2, '1');
nextfullDate = [
next_month_date.getFullYear(),
next_month_date.getMonth() + 1,
]
var next_month = {};
next_month.fullYear = nextfullDate[0]; // 年
next_month.fullMonth = nextfullDate[1]; //月
next_month.dayLength = _this.getMonthDays(next_month.fullMonth, next_month.fullYear);//当前月份总共有多少天
next_month.firstDayWeek = next_month_date.getDay(); //当前月份第一天星期几0~6
next_month.days = [];
//初始化天数
for (let i = 1; i <= next_month.dayLength; i++) {
item = {
ymd: next_month.fullYear + '-' + next_month.fullMonth + '-' + i,
ymd_cn: _this.parseMonth(next_month.fullMonth) + '月' + _this.parseDay(i) + '日',
day: i,
active: '',
disabled: '',
};
//开始时间
item.start_date = _this.compareDate(_this.select_start_ymd, item.ymd) == 2 ? 'active-start' : '';
//中间的日期
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 ? 'active-end' : '';
//超过设置最长日期。禁止选择
item.disabled2 = _this.compareDate(max_reserve_date, item.ymd) == 3 ? 'disabled' : '';
next_month['days'].push(item);
}
//前补0
if (next_month.firstDayWeek > 0) {
for (let i = 0; i < next_month.firstDayWeek; i++) {
next_month['days'].unshift('');
}
}
_this.calendar.push(next_month)
}
console.log(_this.calendar);
},
//格式月份期
parseMonth: function(month){
month = parseInt(month);
if(month <10){
month = '0'+month
}
return month;
}, //格式天
parseDay: function (day) {
day = parseInt(day);
if (day < 10) {
day = '0' + day
}
return day;
},
// 获取每个月的天数
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; //小于
}
},
//点击日期按钮
selectDate:function(item){
var _this = this;
let select_data = item;
console.log(select_data)
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;
}
},computed:{ },mounted(){
var _this = this;
_this.$nextTick(function () {
_this.initDate()
})
}
})
</script>
</html>
里面的备注很清晰,需要存起来下个页面用可以在saveDate这个函数中存进去localStorage中。
案例除了vue不基于任何插件,可以自定义修改,自定义程度高
vue自定义日期选择,类似美团日期选择,日历控件,vue日历区间选择的更多相关文章
- vue日历控件,自定义选择年月 选择年月日 选择年月日时 选择年月日时分,自定义日期范围
下载地址:https://pan.baidu.com/s/1iEZl4kDkEg4ybwqc7aI7vQ 注:功能更加全面的日历控件请访问:https://www.cnblogs.com/mrzhu/ ...
- Flex自定义组件开发之日周月日期选择日历控件
原文:Flex自定义组件开发之日周月日期选择日历控件 使用过DateField的我们都知道,DateField 控件是用于显示日期的文本字段,字段右侧带有日历图标.当用户在控件边框内的 ...
- asp.net 弹出式日历控件 选择日期 Calendar控件
原文地址:asp.net 弹出式日历控件 选择日期 Calendar控件 作者:逸苡 html代码: <%@ Page Language="C#" CodeFile=&quo ...
- 简洁JS 日历控件 支持日期和月份选择
原文出处 以下这个JS日历控件是我的闲暇之余自己编写的,所有的代码全部在IE7/IE8/Firefox下面测试通过, 而且可以解决被iframe层遮盖的问题.现在只提供两种风格(简洁版和古典版)和两种 ...
- JS实现日历控件选择后自动填充
最近在做人事档案的项目,在做项目的初期对B/S这块不是很熟悉,感觉信心不是很强,随着和师哥同组人员的交流后发现,调试程序越来越好了,现在信心是倍增,只要自己自己踏实的去研究.理解代码慢慢的效果就出来了 ...
- Excel日历控件实现下拉选取日期含VB代码实现
以下是Excel2016通过安装控件,实现表格下拉选择日期的一些步骤: 知识准备工作:先了解下如何安装控件,这一部分很重要,excel选择可用宏https://jingyan.baidu.com/ar ...
- My97DatePicker日历控件日报、每周和每月的选择
My97DatePicker日历控件日报.每周和每月的选择 1.设计源代码 <%@ page language="java" import="java.util.* ...
- Repeater控件,判断最少选择一行记录
本演示中,教会大家使用jQuery来判断Repeater控件,最少选择一行记录. 在Repeater控件中,每行第一列放置一个CheckBox,然后在Repeater控件之外,放置一个Button按钮 ...
- js非常强大的日历控件fullcalendar.js, 日期时间库: moment.js
日历控件: https://fullcalendar.io/docs/ https://fullcalendar.io/docs/event_data/events_function/ https:/ ...
- Atitit.ui控件---下拉菜单选择控件的实现select html
Atitit.ui控件---下拉菜单选择控件的实现select html 1. 调用& model的实现 1 2. -----select.jsp------ 1 1. 调用& m ...
随机推荐
- Git学习笔记(windows git之初体验)
阿里国内镜像地址: https://npm.taobao.org/mirrors/git-for-windows/ 最近在学习廖雪峰老师关于git的教程,链接可以在我的首页找到.首先使用国内镜像下载并 ...
- Python面向对象设计小结
转自林海峰老师,学习之余做的笔记. class School: zhuti='学生和老师‘ def __init__(self,name,dic,country): self.mingzi=name ...
- beego框架之orm模块——mysql
参考beego原文:http://beego.me/docs/mvc/model/orm.md#main.go beego ORM 是一个强大的 Go 语言 ORM 框架,orm模块主要是处理MVC中 ...
- java多线程技能-使用多线程-继承Thread类
/* 使用多线程可通过继承Thread类或实现Runnable接口. Thread和Runnable的关系:public class Thread implements Runnable. 使用thr ...
- 吴裕雄--天生自然 python开发学习笔记:解决No module named 'mpl_toolkits.basemap'问题
. 下载: basemap-1.1.0-cp36-cp36m-win_amd64.whl和pyproj-1.9.5.1-cp36-cp36m-win_amd64.whl这两个文件 先运行: 再运行:
- GYCTF Flaskapp[SSTI模板注入 ]
题目复现传送门 学习链接: 找了个师傅的blog先学习一下基础的flask知识 https://www.freebuf.com/column/187845.html(从零学flask) 简单记录一下: ...
- 一、JVM之类加载器
一.什么是JVM 先来看下百度百科的解释: JVM 是 Java Virtual Machine(Java 虚拟机)的缩写,JVM 是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计 ...
- springboot web - 建立路由
一. 测试代码 @RestController @RequestMapping("/book") public class BookController { @PostMappin ...
- 【pattern】设计模式(1) - 单例模式
前言 好久没写博客,强迫自己写一篇.只是总结一下自己学习的单例模式. 说明 单例模式的定义,摘自baike: 单例模式最初的定义出现于<设计模式>(艾迪生维斯理, 1994):“保证一个类 ...
- SQL Server误设置max server memory处理小结
昨天网上一网友说,由于他同事误将"max server memory"设置为10M后,SQL Server数据库登录不了,当时我简单测试了一下,今天有空就顺手将整个过程整理一下,记 ...