基础日历-组件 vue

日历大概长这个样子, 两种颗粒度的。 有上月-到下月的周内日期补充。

平时要么就用插件要么扒网上的代码,也没存过每回都是现用现扒。所以想自己搞一个基础版的方便修改和调整,用vue写的,没用UI库. 代码如下 

<template>
  <div class="calendar">
    <div class="calendar-header padding line-bottom flex justify-between">
      <div class="heder-l">当前月份:{{ currentMonth }}</div>
      <div class="heder-r flex align-center">
        <div class="next-month line" @click="handleLastMonth">上个月</div>
        <div class="next-month line" @click="handleNextMonth">下个月</div>
      </div>
    </div>
    <div class="calendar-main padding-xl">
      <div class="week flex">
        <div class="week-box" v-for="item in weekData" :key="item">
          {{ item }}
        </div>
      </div>
      <div class="calendar-wrapper flex flex-wrap line-top line-left">
        <div
          class="calendar-box padding line-bottom line-right"
          v-for="item in calendarData"
          :key="item.currentDate"
          :class="[
            item.disabled ? 'disabled' : '',
            item.currentDate == currentDate ? 'active' : '',
          ]"
          @click="handleClickDate(item)"
        >
          {{ item.currentDate }}
        </div>
      </div>
    </div>
  </div>
</template>

<script>
var _Date = new Date();
var _year = _Date.getFullYear();
var _month = _Date.getMonth() + 1;
let _day = _Date.getDate();
export default {
  props: {},
  data() {
    return {
      value: new Date(),
      weekData: ["一", "二", "三", "四", "五", "六", "日"], // 星期
      currentMonth: "", //当前月份
      currentDate: `${_year}-${_month}-${_day}`, //当前日期
      calendarData: [], //当月日期集合
    };
  },
  mounted() {
    this.getFullMonth();
  },
  methods: {
    /**
     * 获取整月日期
     */
    getFullMonth() {
      this.currentMonth = `${_year}-${this.formatZero(_month)}`;
      let currentMonthNum = new Date(_year, _month, 0).getDate(); // 获取当月总天数
      let temaryDateArr = [];
      //获取当月日期
      for (let i = 1; i <= currentMonthNum; i++) {
        let day = new Date(_year, _month, 0).setDate(i);
        temaryDateArr.push(this.getCurrentDate(day));
      }
      // start  上月及下月的日期补充
      let lastMonthArr = [];
      let nextMonthArr = [];
      let lastYear = _month == 1 ? _year - 1 : _year; // 上月年份(跨年)
      let lastMonth = _month == 1 ? 12 : _month - 1; //上月月份(跨年)
      let lastMonthNum = new Date(lastYear, lastMonth, 0).getDate(); // 上月总天数
      let lastMonthSurplus = temaryDateArr[0].day - 1; // 上月需要补充的天数,(当前日期的星期数-1)
      let lDate = new Date(`${lastYear}-${lastMonth}`); //上月Date对象
      let nextYear = _month == 12 ? _year + 1 : _year; //下月年份(跨年)
      let nextMonth = _month == 12 ? 1 : _month + 1; // 下月月份(跨年)
      let nexMonthSurplus = 7 - temaryDateArr[temaryDateArr.length - 1].day; //下月需要补充的天数
      let nDate = new Date(`${nextYear}-${nextMonth}`); // 下月Date对象

      //上月日期补充列表
      if (temaryDateArr[0].day > 1) {
        for (let i = 1; i <= lastMonthSurplus; i++) {
          let day = lDate.setDate(lastMonthNum);
          lastMonthArr.unshift(this.getCurrentDate(day));
          lastMonthNum--;
        }
      }

      if (temaryDateArr[temaryDateArr.length - 1].day < 7) {
        //下月日期补充列表
        for (let i = 1; i <= nexMonthSurplus; i++) {
          let day = nDate.setDate(i);
          nextMonthArr.push(this.getCurrentDate(day));
        }
      }
      // end
      this.calendarData = [...lastMonthArr, ...temaryDateArr, ...nextMonthArr];
    },

    /**
     * 获取当前时间戳的日期
     */
    getCurrentDate(timeStamp) {
      let nowDate = new Date(timeStamp);
      let nowYear = nowDate.getFullYear();
      let nowMonth = nowDate.getMonth() + 1;
      let nowDay = nowDate.getDate();
      let obj = {
        disabled: nowYear != _year || nowMonth != _month ? true : false,
        currentDate: `${nowYear}-${nowMonth}-${nowDay}`,
        date: nowDay,
        day: nowDate.getDay() == 0 ? 7 : nowDate.getDay(),
      };
      return obj;
    },

    /**
     * 个位补零
     */
    formatZero(num) {
      if (String(num).length > 1) return num;
      return `0${num}`;
    },
    /**
     * 点击当前日期
     */
    handleClickDate(e) {
      let { currentDate } = e;
      this.currentDate = currentDate;
    },

    /**
     * 切换到上月
     */
    handleLastMonth() {
      if (_month == 1) {
        //跨年
        _year--;
        _month = 12;
      } else {
        _month--;
      }
      this.getFullMonth();
    },

    /**
     * 切换到下月
     */
    handleNextMonth() {
      if (_month == 12) {
        //跨年
        _year++;
        _month = 1;
      } else {
        _month++;
      }
      this.getFullMonth();
    },
  },
};
</script>

<style lang='scss' scoped>
.calendar {
  width: 100%;
  padding: 30px;

  &-header {
    font-size: 16px;
    .next-month {
      font-size: 14px;
      margin-left: 10px;
      padding: 5px 10px;
      border-radius: 4px;
    }
  }

  &-main {
    .week {
      margin-bottom: 30px;
      &-box {
        flex: 1;
        font-size: 18px;
        // font-weight: 600;
        text-align: center;
      }
    }
    .calendar-wrapper {
      .calendar-box {
        width: calc(100% / 7);
        height: 85px;
        font-size: 14px;
        &:hover {
          cursor: pointer;
          background-color: #f2f8fe;
        }
      }
    }
  }
  .active {
    cursor: pointer;
    background-color: #f2f8fe;
  }
  .padding,
  .padding-s,
  .padding-xl {
    box-sizing: border-box;
  }
  .padding {
    padding: 10px;
  }
  .padding-s {
    padding: 5px;
  }
  .padding-xl {
    padding: 20px;
  }
  .flex {
    display: flex;
  }
  .flex-wrap {
    flex-wrap: wrap;
  }
  .justify-between {
    justify-content: space-between;
  }
  .justify-around {
    justify-content: space-around;
  }
  .justify-end {
    justify-content: end;
  }
  .aligin-center {
    align-items: center;
  }
  .shadow {
    box-shadow: 0 2px 12px 0 rgba($color: #000000, $alpha: 0.2);
  }
  .line {
    border: 1px solid #dcdfe6;
  }
  .line-bottom {
    border-bottom: 1px solid #dcdfe6;
  }
  .line-left {
    border-left: 1px solid #dcdfe6;
  }
  .line-right {
    border-right: 1px solid #dcdfe6;
  }
  .line-top {
    border-top: 1px solid #dcdfe6;
  }
  .round {
    border-radius: 8px;
  }
  .disabled {
    color: #c0c4cc;
  }
}
</style>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值