vue2日历组件

这个代码可以直接运行,未防止有组件库没安装,将组件库的代码,转成文字了

vue页面

<template>
  <div class="about">
    <div style="height: 450px; width: 400px">
      <div style="height: 100%; overflow: auto">
        <div class="calendar-title" style="height: 45px">
          <span class="on-title cursor-btn">
            日历
          </span>
          <span>
            <span class="date-title cursor-btn">{
  
  {
              dateTypeFormat('YYYY-mm-dd',new Date())
            }}</span>
            <span>今日</span>
          </span>
        </div>
        <div class="plan-zone">
          <div class="left-btn">
            <!-- <a-icon type="left" @click="prevMonth" /> -->
             <!-- 切换月份----可以换成图标 -->
            <span @click="prevMonth">左</span>
            <span class="cursor-btn">{
  
  { getCurDate() }}</span>
            <span @click="nextMonth">右</span>
            <!-- <a-icon type="right" @click="nextMonth" /> -->
            <!-- <el-button type="primary" @click="goToCurrentDay"
                  >回到今天</el-button
                >-->
          </div>
          <table class="parent-table">
            <thead>
              <th>一</th>
              <th>二</th>
              <th>三</th>
              <th>四</th>
              <th>五</th>
              <th>六</th>
              <th>日</th>
            </thead>
            <tbody>
              <tr v-for="(week, windex) in weeks" :key="windex">
                <td
                  v-for="(day, dindex) in week"
                  :class="{ highlight: isToday(day.date) }"
                  :key="dindex"
                >
                  <div
                    class="content"
                    :class="{
                      faded: !isCurrentMonth(day.date),
                    }"
                  >
                    <div class="top-day" @click="onDate(day)">
                      <a-badge :dot="judgment(day.date.getDate())">{
  
  {
                        day.date.getDate()
                      }}</a-badge>
                    </div>
                    <div class="middle-event"></div>
                    <div class="bottom-event"></div>
                  </div>
                </td>
              </tr>
            </tbody>
          </table>
          <div class="orientation-btn cursor-btn" @click="goToCurrentMonth">
            定位到今天
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>

export default {
  name: "AboutView",
  components: {
  },
  data() {
    return {
      group_data: [],
      current: new Date(),
      today: new Date(),
    };
  },
  computed: {
    weeks() {
      return this.getMonthData(
        this.current.getFullYear(),
        this.current.getMonth() + 1
      );
    },
  },
  methods: {
    dateTypeFormat(fmt, date) {
      let ret;
      const opt = {
        "Y+": date.getFullYear().toString(), // 年
        "m+": (date.getMonth() + 1).toString(), // 月
        "d+": date.getDate().toString(), // 日
        "H+": date.getHours().toString(), // 时
        "M+": date.getMinutes().toString(), // 分
        "S+": date.getSeconds().toString(), // 秒
        // 有其他格式化字符需求可以继续添加,必须转化成字符串
      };
      for (const k in opt) {
        ret = new RegExp("(" + k + ")").exec(fmt);
        if (ret) {
          fmt = fmt.replace(
            ret[1],
            ret[1].length === 1 ? opt[k] : opt[k].padStart(ret[1].length, "0")
          );
        }
      }
      return fmt;
    },
    judgment(val) {
      let dete = this.getCurDate() + "-" + val;
      let flag = false;
      this.group_data.forEach((item) => {
        if (item.name === dete) {
          flag = true;
        }
      });
      return flag;
    },
    onDate(val) {
      this.current = val.date;
    },
    getCurDate() {
      var date = this.current;
      var year = date.getFullYear();
      var month = date.getMonth() + 1; // getMonth() returns a zero-based value (0-11)
      if (month < 10) {
        month = "0" + month; // add a leading zero if the month is a single digit
      }
      return year + "-" + month;
    },
    isToday(date) {
      // let today = new Date()
      return (
        date.getDate() === this.current.getDate() &&
        date.getMonth() === this.current.getMonth() &&
        date.getFullYear() === this.current.getFullYear()
      );
    },
    goToCurrentDay() {
      this.current = new Date(this.today);
    },
    isCurrentMonth(date) {
      return date.getMonth() === this.current.getMonth();
    },
    prevMonth() {
      this.current.setMonth(this.current.getMonth() - 1);
      this.current = new Date(this.current);
    },
    nextMonth() {
      this.current.setMonth(this.current.getMonth() + 1);
      this.current = new Date(this.current);
    },
    goToCurrentMonth() {
      this.current = new Date(this.today);
    },
    getMonthData(year, month) {
      let weeks = [];
      let firstDay = new Date(year, month - 1, 1); // 这个月的第一天
      let lastDayOfCurrentMonth = new Date(year, month, 0); // 这个月的最后一天
      let lastDayOfPrevMonth = new Date(year, month - 1, 0); // 上个月的最后一天

      //这里的0有一个特殊的意义,它可以返回上个月的最后一天。也就是说,如果你想知道某个月有多少天,你可以创建一个日期对象,年份和月份设置为你想知道的月份,日期设置为0,然后调用getDate()方法,返回的就是那个月的天数。
      // new Date(year, month - 1, 0) 最后一个参数,超过当月天数重新排序,比如1月31天,最后一个参数为33返回2
      let startDayOfWeek = firstDay.getDay() === 0 ? 7 : firstDay.getDay(); // 开始是周几
      let dayCount = 1; // 当前日期的变量,初始值为1
      // 上一个月的天数
      let prevMonthDayCount = lastDayOfPrevMonth.getDate() - startDayOfWeek + 2; // 这是为了在日历中填充上个月的日期。
      for (let i = 0; i < 6; i++) {
        let week = [];
        for (let j = 0; j < 7; j++) {
          // 日期为上个月的日期,然后将这个日期对象添加到`week`数组中,同时`prevMonthDayCount`加1。
          if (i === 0 && j < startDayOfWeek - 1) {
            week.push({ date: new Date(year, month - 2, prevMonthDayCount++) });
            // 日期为下个月的日期,然后将这个日期对象添加到`week`数组中,同时`dayCount`加1
          } else if (dayCount > lastDayOfCurrentMonth.getDate()) {
            week.push({
              date: new Date(
                year,
                month,
                dayCount++ - lastDayOfCurrentMonth.getDate()
              ),
            });
            // 日期为这个月的日期,然后将这个日期对象添加到`week`数组中,同时`dayCount`加1
          } else {
            week.push({ date: new Date(year, month - 1, dayCount++) });
          }
        }
        weeks.push(week);
      }
      return weeks;
    },
  },
};
</script>
<style lang="less" scoped>
.cursor-btn {
  cursor: pointer;
}
.faded {
  opacity: 0.3;
}
.highlight {
  background: #3f7afe;
  border-radius: 50px;
  color: #fff;
}
.plan-zone {
  margin-top: 10px;
  border: 1px solid #ddd;
  border-radius: 4px;
  .left-btn {
    display: flex;
    justify-content: space-evenly;
    align-items: center;
    height: 38px;
    border-bottom: 1px solid #d4d4d4;
  }
  .orientation-btn {
    display: flex;
    justify-content: space-evenly;
    align-items: center;
    height: 32px;
    border-top: 1px solid #d4d4d4;
    color: #819cef;
  }
  .right-btn {
    button.new {
      background-color: #fff;
      border: 1px solid #fff;
      color: #409eef;
      position: relative;
      &::before {
        content: "";
        width: 8px;
        height: 8px;
        border-radius: 50%;
        position: absolute;
        top: 7px;
        left: -3px;
        background-color: #409eef;
      }
    }
    button.ing {
      background-color: #fff;
      border: 1px solid #fff;
      color: #ff974a;
      position: relative;
      &::before {
        content: "";
        width: 8px;
        height: 8px;
        border-radius: 50%;
        position: absolute;
        top: 7px;
        left: -3px;
        background-color: #ff974a;
      }
    }
    button.finish {
      background-color: #fff;
      border: 1px solid #fff;
      color: #3dd599;
      position: relative;
      &::before {
        content: "";
        width: 8px;
        height: 8px;
        border-radius: 50%;
        position: absolute;
        top: 7px;
        left: -3px;
        background-color: #3dd599;
      }
    }
  }
}
.parent-table {
  border-collapse: collapse;
  table-layout: fixed;
  text-align: center;
  width: calc(100% - 70px);
  /* margin-top: 1.04167vw; */
  margin: 15px 35px;
  thead {
    border-bottom: 1px solid #d4d4d4;
  }
  th,
  td {
    width: 14.4%;
    // border: 1px solid #ddd;
  }
  td {
    padding: 2px 3px;

    .content {
      position: relative;
      height: 32px;
      line-height: 32px;
    }
    vertical-align: top;
    .top-day {
      cursor: pointer;
      text-align: center;
      font-size: 13px;
    }
  }
}
.table-date {
  display: flex;
  > div {
    flex: 1;
  }
}
.schedule-right {
  height: calc(48% - 20px);
  padding-top: 8px;
}
.calendar-title2 {
  height: 45px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 8px 4px 8px;
  border-bottom: 1px solid #e8e8e8;
  margin-bottom: 8px;
  font-size: 15px;
  font-weight: 600;
  // margin-top: 8px;
  .date-title {
    color: #819cef;
  }
}
.calendar-title {
  height: 45px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 8px 4px 8px;
  border-bottom: 1px solid #e8e8e8;
  margin-bottom: 8px;
  font-size: 15px;
  font-weight: 600;
  .date-title {
    color: #819cef;
  }
}
</style>
相关推荐
谢尔登11 分钟前
【Node.js】Common JS 和 ES Module 对于导出值的探究
javascript·elasticsearch·node.js
小慧102442 分钟前
ROS2快速入门0--节点
开发语言·javascript·ecmascript
不吃香菜mm1 小时前
Vue方法、计算机属性及侦听器
前端·javascript·vue.js
nuIl1 小时前
VSCode 架构分析:依赖注入和组件
前端·javascript·架构
疯狂的沙粒1 小时前
HTML和CSS相关的问题,为什么页面加载速度慢?
前端·css·html
远洋录2 小时前
Vue 开发者的 React 实战指南:组件设计模式篇
前端·人工智能·react
疯狂的沙粒2 小时前
React 中事件机制详细介绍:概念与执行流程如何更好的理解
前端·javascript·react.js
TomcatLikeYou2 小时前
从excel提取和过滤数据到echarts中绘制图
前端·echarts·excel
傻小胖2 小时前
# React Router 路由导航hooks使用总结
前端·react.js·前端框架
枫星辰2 小时前
买房焦虑,打造成都二手房交易行情大屏-实现篇
前端