简单日历的实现

1.示例图

image.png

2.代码实现

<template>
  <div class="main_content">
    <div class="year">
      <img alt="上一步" src="../assets/icon_back@2x.png" @click="preMon" />
      <span>{{ this.year }}年{{ this.month }}月</span>
      <img alt="下一步" src="../assets/icon_back@2x.png" @click="nextMon" style="transform: scaleX(-1)"/>
    </div>
    <div class="calendar">
      <div class="week" @click="changeWeek(changeWeekFlag)">
        <div class="week-text" v-for="(item, index) in weekData" :key="index">
          {{ item }}
        </div>
      </div>
      <div class="day">
        <div class="day-text" v-for="(item, index) in days" :key="index">
          <div class="week-text" :style="getColor(item,index)" @click="getChange(item,index)" v-on:click="clickItem(item,index)" :class="addColor(item)">
            {{ item.day }}
            <div :class="smallDot(item)">&nbsp;</div>
          </div>
        </div>
      </div>
      <img
        alt="收起" 
        src="../assets/Fast-top-ico@2x.png"
        :style="this.packUpFlag?'':'transform:rotate(180deg);'"
        @click="packUp(packUpFlag)"
      />
    </div>
    <!-- <button @click="changeWeek(changeWeekFlag)" class="btn"> 设置从{{ !this.changeWeekFlag ? "周一" : "周日" }}开头 切换按钮 </button> -->
  </div>
</template>

<script>
export default {
  name: "calendarView",
  data() {
    return {
        year: null, //当前年份
        month: null, //当前月份
        day: null, //当前日
        weekData: [], //周的列表
        days: [], //当月的日期列表
        // daynum: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], //1-12月每个月的天数(方法一)
        index: null, //日期数组的索引

        changeWeekFlag: false, // 周一/周日开头的标识(默认周一true)
        acolor: true, // 是否展示颜色
        yearChecked: null, // 选中年
        monthChecked: null, // 选中月
        dayChecked: null, // 选中天

        todayYearChecked: new Date().getFullYear(), // 默认选中年
        todayMonthChecked: new Date().getMonth() + 1, // 默认选中月

        arr: [], // 记录浏览数据
        checkFlag: false, // 有选中日期的标识
        packUpFlag: true, // 是否收起的标识(默认展开)
        todayIndex: null, // 今日的索引
    };
  },
  methods: {
    // 设置从周一或周日开头(默认周一)
    changeWeek(flag) {
        this.changeWeekFlag = !flag;
        // 周一开头
        if (!flag) {
            this.weekData = ["一", "二", "三", "四", "五", "六", "日"];
        } else {
            this.weekData = ["日", "一", "二", "三", "四", "五", "六"];
        }
        this.nowMonth();
        this.packUpFlag = true;
        if(this.changeWeekFlag) {
          this.index = this.index - 1
        } else {
          this.index = this.index + 1
        }
    },
    // 计算当月天数
    nowMonth() {
        let daylength = new Date(this.year, this.month, 0).getDate(); // 直接计算出每月天数,可去掉平闰年判断(方法二)
        // let daylength = this.daynum[this.month - 1]; //1-12月每个月的天数(方法一)
        this.days.splice(0); //清空原数组

        // 当月
        for (let i = 0; i < daylength; i++) {
            this.days.push({
                type: 0,
                fullYear: this.year,
                month: this.month,
                day: i + 1,
            });
        }

        // 上一月
        let firstDate = new Date(this.year, this.month - 1, 1).getDay(); // 获取本月的1号是周几
        let lastDaylength = new Date(this.year, this.month, -1).getDate(); // 上月天数
        // let lastDaylength = this.daynum[this.month - 2]; //1-12月每个月的天数(方法一)
        if (this.changeWeekFlag) {
            if (firstDate == 0) {
                firstDate = 7;
            }
            firstDate = firstDate - 1;
        }
        for (let i = 0; i < firstDate; i++) {
            this.days.unshift({
                type: -1,
                fullYear: this.month > 1?this.year:this.year - 1,
                month: this.month > 1?this.month - 1:12,
                day: lastDaylength - i,
            });
        }

        // 下一月 满格补全6行7列(格式一)
        for (let i = 1; i <= 42 - firstDate - daylength; i++) {
            this.days.push({
                type: 1,
                fullYear: this.month < 12?this.year:this.year + 1,
                month: this.month < 12?this.month + 1:1,
                day: i,
            });
        }
        // // 下一月 不补全整个周(格式二)
        // let len = this.days.length%7
        // if(len != 0) {
        //     for (let i = 1; i < 8 - len; i++) {
        //         this.days.push({
        //             type: 1,
        //             fullYear: this.month < 12?this.year:this.year + 1,
        //             month: this.month < 12?this.month + 1:1,
        //             day: i,
        //         });
        //     }
        // }
    },
    // 折行收起 (切换本周)
    packUp(packUpFlag) {
        this.packUpFlag = !packUpFlag;
        if(!packUpFlag) { //展开,展示整月
            this.nowMonth();
        } else { //收起,只展示一周
            this.year = this.yearChecked?this.yearChecked:this.todayYearChecked;
            this.month = this.monthChecked?this.monthChecked:this.todayMonthChecked;
            this.nowMonth();
            if(this.checkFlag == false) {
                // 默认日期 无选中点击日期
                let firstIndex = this.todayIndex - this.todayIndex % 7;
                this.days = this.days.slice(firstIndex, firstIndex + 7);
            } else {
                // 点击后 记录开头索引
                let index;
                if(this.changeWeekFlag) {
                    index = this.index;
                } else {
                    index = this.index + 1;
                }
                let firstIndex = index - index % 7; //一周开头的索引
                this.days = this.days.slice(firstIndex, firstIndex + 7); //通过索引 截取一周的数据
            }
        }
    },
    // 上个月
    preMon() {
        if (this.month > 1) {
            this.month--;
        } else {
            this.year--;
            this.month = 12;
            // this.isYear(this.year); //平闰年2月的天数(方法一)
        }
        this.nowMonth();
        this.packUpFlag = true;
    },
    // 下个月
    nextMon() {
        if (this.month < 12) {
            this.month++;
        } else {
            this.year++;
            this.month = 1;
            // this.isYear(this.year); //平闰年2月的天数(方法一)
        }
        this.nowMonth();
        this.packUpFlag = true;
    },
    // 点击置灰日期,跳转到对应月份的日期
    getChange(item) {
        if (item.type == -1) {
            this.preMon();
        }
        if (item.type == 1) {
            this.nextMon();
        }
    },
    // 不是本月的日期置灰
    getColor(d, index) {
        // 无法选中某天
        if(
            d.fullYear == 2022 &&
            d.month == 7 &&
            d.day == 1
        ) {
            return "pointer-events:none; background:#dee1e6; border-radius: 50%;";
        }

        // 当前日期 默认选中
        if (
            d.fullYear == new Date().getFullYear() &&
            d.month == new Date().getMonth() + 1 &&
            d.day == new Date().getDate()
        ) {
            this.todayIndex = index; // 默认今日 记录索引
            return "color: #fff; background: #dd4156; border-radius: 50%;";
        }
        let color = d.type == 0 ? "color: #000" : "color: #c0c4cc;";
        return color;
    },
    // 点击选中
    clickItem(item, index) {
        if(item.type == 0) {
            this.index = index; //选中日期 记录索引
            this.checkFlag = true; //有选中日期
            this.yearChecked = item.fullYear;
            this.monthChecked = item.month;
            this.dayChecked = item.day;

            // 记录浏览数据
            this.arr.push(item);
        }
    },
    //选中颜色改变
    addColor(item) {
        if (this.dayChecked == item.day && this.monthChecked == item.month && item.type == 0) {
            return { active: this.acolor };
        }
    },
    // 记录浏览数据
    smallDot(item) {
        for (let i of this.arr) {
            if (item.type == 0 && i.day == item.day && i.month == item.month) {
                return { history: this.acolor };
            }
        }
    },
    // // 判断闰年或平年
    // isYear() {
    //     // console.log(this.year);
    //     if(this.year % 4 == 0 && this.year % 100 != 0 || this.year % 400 == 0){
    //         this.daynum[1] = 29;
    //         // console.log("闰年");
    //     }else{
    //         this.daynum[1] = 28;
    //         // console.log("平年");
    //     }
    // },
  },
  mounted() {
    let time = new Date();
    this.year = time.getFullYear(); //获取当前年份
    this.month = time.getMonth() + 1; //获取当前月份
    this.day = time.getDate(); //获取当前日
    // this.isYear(this.year); //判断平年闰年
    // this.nowMonth();
    this.changeWeek(this.changeWeekFlag);
  },
};
</script>

<style scoped lang="less">
.main_content {
  // width: 100%;
  width: 400px;
  height: 100%;
  margin: 0 auto;
  .year {
    height: 24px;
    padding: 5px;
    font-size: 14px;
    line-height: 24px;
    display: flex;
    justify-content: space-between;
    justify-items: center;
    img {
      width: 13px;
      height: 13px;
      padding: 0 40px;
    }
  }

  .calendar {
    font-size: 12px;
    text-align: center;
    // height: calc(100% - 34px);
    .week {
      height: 16px;
      padding: 8px;
      display: flex;
      justify-content: space-around;
      justify-items: center;
      border-bottom: 1px solid #e4e7ed;
    }
    .week-text {
      width: 24px;
      height: 24px;
      line-height: 24px;
      cursor: pointer;
      position: relative;
    }
    .active {
      color: #fff !important;
      background: #5ca05f !important;
      border-radius: 50%;
    }

    .day {
      // height: calc(100% - 49px);
      padding: 8px;
      display: flex;
      justify-content: space-around;
      justify-items: center;
      flex-wrap: wrap;
      .day-text {
        width: 50px;
        // width: 100%;
        display: flex;
        justify-content: space-around;
        justify-items: center;
        margin: 10px 0;
      }
    }
  }

  .btn {
    margin: 50px auto;
    background: rgb(131, 177, 245);
    color: #fff;
    border: 0;
    padding: 5px;
  }

  .history {
    width: 3px;
    height: 3px;
    background: red;
    border-radius: 50%;
    margin: 2px auto;
  }
}
</style>
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容