vue移动端 日历 左右点击版本 非滑动

需求:

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拉取源代码,需要留言即可

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值