Vue 日历时间选着器(复制可用)

工作笔记:写一个时间以日历的方式选着日期

直接上代码,复制做成组件便可使用。

<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>

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值