JavaScriptVue

Vue纯JS实现日历

2020-03-12  本文已影响0人  西瓜鱼仔

效果图

不说废话,先上效果图:


实现代码

<template>
  <div class="calender">
    <div class="top">
      <img src="./last-year.png" @click="handleShowLastYear"/>
      <img src="./last-month.png" style="margin-left: 50px" @click="handleShowLastMonth"/>
      <span class="top_date">{{year}}年{{month}}月</span>
      <img src="./next-month.png" style="margin-left: 40px" @click="handleShowNextMonth"/>
      <img src="./next-year.png" style="margin-left: 50px" @click="handleShowNextYear"/>
    </div>
    <div class="date_wrap">
      <div class="week">
        <span>日</span>
        <span>一</span>
        <span>二</span>
        <span>三</span>
        <span>四</span>
        <span>五</span>
        <span>六</span>
      </div>
      <div class="day">
        <span v-for="(item,index) in lastDays" :key=index class="otherDay">
          {{item}}
        </span>
        <span v-for="(item,index) in days" :key=index+50
              :class="{current:currentDay===year.toString()+month.toString()+item}">
          {{item}}
        </span>
        <span v-for="(item,index) in nextDays" :key=index+100 class="otherDay">
          {{item}}
        </span>
      </div>
    </div>
  </div>
</template>

<script>
    export default {
        name: 'calender',
        data() {
            return {
                year: '',
                month: '',
                lastDays: [],
                days: [],
                nextDays: [],
                currentDay: '',
            }
        },
        methods: {
            //控制当前日期显示特殊样式
            handleShowDateStyle() {
                let now = new Date();
                this.currentDay = now.getFullYear().toString() + (now.getMonth() + 1).toString() + now.getDate().toString()
            },
            //获取当前年月份天数
            getDays(Y, M) {
                return new Date(Y, M, 0).getDate();
            },
            //得到当前年,这个月的一号是周几
            getWeek(Y, M) {
                let now = new Date();
                now.setFullYear(this.year);
                now.setMonth(this.month - 1);
                now.setDate(1);
                return now.getDay();
            },
            pushDays() {
                //为了完整和美观,日历展示为7列*6行,一共展示42天
                //将这个月多少天加入数组days
                for (let i = 1; i <= this.getDays(this.year, this.month); i++) {
                    this.days.push(i)
                }
                //将上个月后面天数加入数组lastDays
                for (let i = 0; i < this.getWeek(this.year, this.month); i++) {
                    let lastMonthDays = this.getDays(this.year, this.month - 1);
                    this.lastDays.unshift(lastMonthDays - i)
                }
                //将下个月前几天加入数组nextDays
                let _length = this.days.length + this.lastDays.length;
                for (let i = 1; i < 43 - _length; i++) {
                    this.nextDays.push(i)
                }
            },
            getDate() {
                let now = new Date();
                this.year = now.getFullYear();
                this.month = now.getMonth() + 1;
                this.pushDays();
            },
            handleShowNextMonth() {
                this.lastDays = [];
                this.days = [];
                this.nextDays = [];
                if (this.month < 12) {
                    this.month = this.month + 1;
                    this.pushDays();
                } else {
                    this.month = this.month = 1;
                    this.year = this.year + 1;
                    this.pushDays();
                }
            },
            handleShowLastMonth() {
                this.lastDays = [];
                this.days = [];
                this.nextDays = [];
                if (this.month > 1) {
                    this.month = this.month - 1;
                    this.pushDays();
                } else if (this.year > 1970) {
                    this.month = 12;
                    this.year = this.year - 1;
                    this.pushDays();
                } else {
                    alert("不支持查找1970年之前的日期!")
                }
            },
            handleShowNextYear() {
                this.lastDays = [];
                this.days = [];
                this.nextDays = [];
                this.year = this.year + 1;
                this.pushDays();
            },
            handleShowLastYear() {
                this.lastDays = [];
                this.days = [];
                this.nextDays = [];
                if (this.year > 1970) {
                    this.year = this.year - 1;
                    this.pushDays();
                } else {
                    alert("不支持查找1970年之前的日期!")
                }
            }
        },
        mounted() {
            this.getDate();
            this.handleShowDateStyle();
        }
    }
</script>
<style scoped>
  .calender {
    width: 600px;
  }

  .top {
    width: 400px;
    height: 30px;
    line-height: 30px;
    margin-left: 120px;
  }

  .top_date {
    width: 100px;
    font-size: 18px;
    color: #2d8cf0;
    margin-left: 40px;
  }

  .date_wrap {
    margin-top: 12px;
  }

  .week {
    width: 100%;
    font-size: 17px;
    font-weight: 500;
    display: flex;
    margin-left: 15px;
  }

  .week span {
    margin-left: 51px;
  }

  .day {
    display: flex;
    width: 480px;
    flex-direction: row;
    font-size: 16px;
    flex-wrap: wrap;
    margin-left: 38px;
  }

  .day span {
    margin-top: 13px;
    width: 14.28%;
    text-align: center;
  }

  .current {
    color: #2d8cf0;
    font-weight: bold;
  }

  .current:after {
    content: "";
    display: block;
    width: 16px;
    border-bottom: #2d8cf0 2px solid;
    margin: 0 auto;
  }

  .otherDay {
    color: #c5c8ce;
  }

</style>

核心方法是pushDays()

思路

为了日历的完整和美观,采用的6行 × 7列,共42天的布局

  1. 首先计算出本月的天数以及本月1号是周几(1号永远在日历的第1行)
  2. 根据本月1号是周几,填充本月1号前面的空位
  3. 将本月日期填充进去
  4. 计算剩余空位,填充日历最后面的空位

素材

日历中切换年月的图标素材如下:


last-year.png
next-year.png
last-month.png
next-month.png
上一篇下一篇

猜你喜欢

热点阅读