日历表实现

一、使用技术
Vue
二、实现思路
1、一个月最多占用的是6周,因此日历表是日期分为6组。
2、获得当前月份有多少天,当前月份第一天是星期几。
3、获得上一个月份有多少天,根据获得的当前月份第一天来计算当前月份第一周从上个月几号开始。
4、第一周第一天到当前月的第一天即为上个月日期,然后根据当前月份的天数依次排开,剩余的天数即为下个月的日期。
5、判断今天日期是不是在当前月中,在的话标红。
三、注意事项
1、具体的颜色样式需求可以根据自己的需要进行更改。
2、想要获取点击的日期只需要添加点击事件进行获取即可。
四、效果图

calender.png

效果视频链接:https://6d79-mycloud-m7997-1301347483.tcb.qcloud.la/blogs/calender.mp4
五、HTML代码

<div class="operation">
      <div @click="beforeDate">上一个月</div>
      <div>{{ currentYear + "-" + currentMonth }}</div>
      <div @click="afterDate">下一个月</div>
    </div>
    <div class="calender-container">
      <div class="calender-title">
        <span class="title-item" v-for="item in weekDays" :key="item">{{ item}}</span>
      </div>
      <div
        class="calender-title1"
        v-for="(week, index) in monthDays"
        :key="index"
      >
        <!-- 不是当前月份置灰显示 -->
        <!-- 是今天的话颜色为红色 -->
        <span
          v-for="(dayObj, index1) in week"
          :class="[
            'title-item',
            dayObj.month != 'current' ? 'not-current-month' : '',
            isToday(currentYear, currentMonth, dayObj.day),
          ]"
          :key="index1"
          >
            <span>{{ dayObj.day }}</span>
        </span>
      </div>
    </div>

六、JS代码

data() {
    return {
      // 当前年
      currentYear: 0,
      // 当前月
      currentMonth: 0,
      // 当前日
      currentDay: 0,
      weekDays: ["日", "一", "二", "三", "四", "五", "六"],
      // 月份日期数组
      monthDays: null,
      // 今天日期
      today: "",
    };
  },
created() {
    // 获得今天日期
    let currentDate = new Date();
    // 获得当前年
    this.currentYear = currentDate.getFullYear();
    // 获得当前月
    this.currentMonth = currentDate.getMonth() + 1;
    // 获得今天日期
    this.today =
      this.currentYear + "-" + this.currentMonth + "-" + currentDate.getDate();
      this.monthDays = this.getCurrentDateArray(
      this.currentYear,
      this.currentMonth
    );
  },
methods: {
 // 判断切换的日期中哪一天是今天
    isToday(year, month, day) {
      return this.today === year + "-" + month + "-" + day ? "is_today" : "";
    },
    // 上一个月份
    beforeDate() {
      if (this.currentMonth == 1) {
        this.currentYear = this.currentYear - 1;
        this.currentMonth = 12;
      } else {
        this.currentYear = this.currentYear;
        this.currentMonth = this.currentMonth - 1;
      }
      this.monthDays = this.getCurrentDateArray(this.currentYear,this.currentMonth);
    },
    // 下一个月份
    afterDate() {
      if (this.currentMonth == 12) {
        this.currentYear = this.currentYear + 1;
        this.currentMonth = 1;
      } else {
        this.currentYear = this.currentYear;
        this.currentMonth = this.currentMonth + 1;
      }
      this.monthDays = this.getCurrentDateArray(this.currentYear,this.currentMonth);
    },
    // 获得当前月的日期数组
    // {
    //   first:[1,2,3,4,5,6,7],
    //   second:[8,9,10,11,12,13,14],
    //   ...
    // }
    getCurrentDateArray(year, month) {
      // 获得当前月多少天以及当前月第一天是周几
      let { monthDaysCount, firstDayWeek } = this.getCurrentMonthDayNum(year,month);
      // 获得当前月份第一天所在周的上个月起始日期
      let beforeMonthDays =
        this.getBeforeMonth(year, month).monthDaysCount - firstDayWeek + 1;
      let days = [];
      var afterDay = 0;
      // 一个月份的时间跨度最多不超过六周即42天
      for (let index = 0; index < 42; index++) {
        // 上一个月日期 当前月份1号之前的天数都是上个月的日期
        if (index < firstDayWeek) {
          days.push({ day: beforeMonthDays++, month: "before" });
          // 当前月日期
        } else if (index >= firstDayWeek &&index < firstDayWeek + monthDaysCount) {
          days.push({ day: index - firstDayWeek + 1, month: "current" });
          // 下一个月日期
        } else {
          days.push({ day: ++afterDay, month: "after" });
        }
      }
      // 日期分组分为6组
      let daysObj = {};
      daysObj.first = days.slice(0, 7);
      daysObj.second = days.slice(7, 14);
      daysObj.third = days.slice(14, 21);
      daysObj.forth = days.slice(21, 28);
      daysObj.fifth = days.slice(28, 35);
      daysObj.sixth = days.slice(35, 42);
      return daysObj;
    },
    // 获得前一个月天数
    getBeforeMonth(year, month) {
      let beforeYear = undefined;
      let beforeMonth = undefined;
      if (month == 1) {
        beforeYear = year - 1;
        beforeMonth = 12;
      } else {
        beforeYear = year;
        beforeMonth = month - 1;
      }
      return this.getCurrentMonthDayNum(beforeYear, beforeMonth);
    },
    // 获得后一个月天数
    getAfterMonth(year, month) {
      let afterYear = undefined;
      let afterMonth = undefined;
      if (month == 12) {
        afterYear = year + 1;
        afterMonth = 1;
      } else {
        afterYear = year;
        afterMonth = month + 1;
      }
      return this.getCurrentMonthDayNum(afterYear, afterMonth);
    },
    // 获得当前月天数
    getCurrentMonthDayNum(year, month) {
      let leapYear = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
      let notLeapYear = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
      // 获得当前月份第一天是周几
      let firstDayWeek = new Date(year + "-" + month + "-" + "1").getDay();
      return {
        monthDaysCount: this.isLeapYear(year)
          ? leapYear[month - 1]
          : notLeapYear[month - 1],
        firstDayWeek,
      };
    },
    // 判断是否是闰年
    isLeapYear(year) {
      return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
    },
  },

七、css代码

.operation {
  display: flex;
  justify-content: space-between;
  padding: 10px 20px;
}
.operation > div {
  border: solid 1px #cccccc;
  padding: 5px 8px;
  font-size: 8px;
  border-radius: 5px;
}
.calender-title {
  display: flex;
  justify-content: space-around;
  background: #ccc;
  padding-top: 5px;
  padding-bottom: 5px;
}
.calender-title1 {
  display: flex;
  justify-content: space-around;
  background: white;
  padding-top: 5px;
  padding-bottom: 5px;
}
.title-item {
  color: #666;
  display: block;
  width: 14%;
  text-align: center;
}
.not-current-month {
  color: #ccc;
}
.is_today {
  background: #eb4450;
  color: white;
  border-radius: 5px;
}
.mouse-hover:hover {
  background: wheat;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,640评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,254评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,011评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,755评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,774评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,610评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,352评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,257评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,717评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,894评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,021评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,735评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,354评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,936评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,054评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,224评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,974评论 2 355

推荐阅读更多精彩内容