简单封装一个基于vue的日历组件calendar

这是效果

在这里插入图片描述

直接上代码

<template>
  <div class="calendar">
    <div class="title">
      <h2>日历</h2>
      <div class="checks">
        <span @click="onCheckDate('reduction','year')" class="check-item">&lt;&lt;</span>
        <span @click="onCheckDate('reduction','month')" class="check-item">&nbsp;&lt;&nbsp;</span>
        <span class="check-item-date">{{getYearMonth}}</span>
        <span @click="onCheckDate('add','month')" class="check-item">&nbsp;&gt;&nbsp;</span>
        <span @click="onCheckDate('add','year')" class="check-item">&gt;&gt;</span>
      </div>
    </div>
    <div class="calendar-days">
      <div class="calendar-header">
        <span v-for="(item,index) in calendarHeader" :key="index" class="header-item">{{item}}</span>
      </div>
      <div class="day-row" v-for="row in 6" :key="row">
        <span @click="onSelectDay(row,line)" class="day-line" :class="{'select-day':row==selectDay.row&&line==selectDay.line,'not-current-month':notCurrentMonth(visibleDays[(row-1)*7+line-1]),'current-day':currentDay(visibleDays[(row-1)*7+line-1])}" v-for="line in 7" :key="line">
          {{visibleDays[(row-1)*7+line-1] | getDay}}
        </span>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      calendarHeader: ["日", "一", "二", "三", "四", "五", "六"],
      nowDate: new Date(),
      selectDay: {
        row: null,
        line: null
      }
    }
  },
  computed: {
    // 当前日期换为年月
    getYearMonth() {
      const date = new Date(this.nowDate);
      const year = date.getFullYear();
      let month = date.getMonth();
      month = month + 1;
      month < 10 ? month = "0" + month : month = month;
      return `${year}${month}月`;
    },
    visibleDays() {
      const { year, month } = this.getYearMonthDay(new Date(this.nowDate)); // 获取当前年月
      let currentFirstDay = new Date(year, month, 1); // 当前月份的第一天
      const week = currentFirstDay.getDay(); // 周几
      let startDay = currentFirstDay - week * 24 * 60 * 60 * 1000; // 开始时间
      // 循环42天(保证日历格式统一   6*7)
      let dayArr = new Array();
      for (let i = 0; i < 42; i++) {
        dayArr.push(new Date(startDay + i * 24 * 60 * 60 * 1000));
      };
      return dayArr;
    }
  },
  methods: {
    // 切换年月事件
    onCheckDate(mode, category) {
      const { year, month } = this.getYearMonthDay(new Date(this.nowDate));
      if (mode == "add") {
        if (category == "year") {
          this.nowDate = new Date(year + 1, month, 1);
        } else {
          this.nowDate = new Date(year, month + 1, 1);
        }
      } else {
        if (category == "year") {
          this.nowDate = new Date(year - 1, month, 1);
        } else {
          this.nowDate = new Date(year, month - 1, 1);
        }
      }
    },
    // 点击日期事件
    onSelectDay(row, line) {
      this.selectDay.row = row;
      this.selectDay.line = line;
    },
    // 判断哪个是当前日
    currentDay(date) {
      const currentDate = this.getYearMonthDay(new Date(date));
      const nowDate = this.getYearMonthDay(new Date());
      if (currentDate.year == nowDate.year && currentDate.month == nowDate.month && currentDate.day == nowDate.day) {
        return true;
      } else {
        return false;
      }
    },
    // 判断当前日期是不是本月
    notCurrentMonth(date) {
      if (this.getYearMonthDay(new Date(date)).month != this.getYearMonthDay(new Date(this.nowDate)).month) {
        return true;
      } else {
        return false;
      }
    },
    // 获取年月日
    getYearMonthDay(date) {
      const year = date.getFullYear();
      const month = date.getMonth();
      const day = date.getDate();
      return { year, month, day };
    }
  },
  filters: {
    // 日期转换为日
    getDay(date) {
      return new Date(date).getDate();
    }
  },
  mounted() {
  }
}
</script>

<style lang="less" scoped>
.calendar {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  // 头部
  .title {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 15px;
    .check-item-date {
      margin: 0 10px;
    }
    .check-item {
      margin: 0 10px;
      cursor: pointer;
      user-select: none;
      display: inline-block;
      &:hover {
        color: #000000;
        transform: scale(1.1);
      }
    }
  }
  // 日历
  .calendar-days {
    flex: 1;
    display: flex;
    flex-direction: column;
    .calendar-header {
      display: flex;
      margin: 10px 0;
      user-select: none;
      .header-item {
        display: block;
        flex: 1;
        text-align: center;
        font-weight: bold;
      }
    }
    .day-row {
      flex: 1;
      display: flex;
      .day-line {
        display: flex;
        justify-content: center;
        align-items: center;
        flex: 1;
        cursor: pointer;
        transition: all 0.2s;
        user-select: none;
        &:hover {
          background-color: #c3d3eb;
        }
      }
      // 非本月
      .not-current-month {
        color: #aaa;
      }
      // 当前日期
      .current-day {
        background-color: #2475ec;
        color: #fff;
      }
      // 选中的日期
      .select-day {
        background-color: #c3d3eb;
      }
    }
  }
}
</style>
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值