vue移动端日历组件


<template>
  <div class="calendar">
    <div class="header">
      <span @click="prevMonth"></span>
      <h2>{{ year }}{{ month }}</h2>
      <span @click="nextMonth"></span>
    </div>
    <div class="box">
      <div class="box-top">
        <div class="box-top-content">
          <div></div>
          <div></div>
          <div></div>
          <div></div>
          <div></div>
          <div></div>
          <div></div>
        </div>
      </div>
      <div class="box-bottom">
        <div class="box-bottom-content" v-for="(week, index) in weeks" :key="index">
          <div class="box-bottom-content-box" v-for="(day, i) in week" :key="i" :class="{ today: day.today, selected: day.selected }" @click="selectDay(day)">
            {{ day.date && day.date.getDate() }}
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      year: 2021,
      month: 1,
      selectedDate: null,
    };
  },
  computed: {
    weeks() {
      const weeks = [];
      const firstDayOfMonth = new Date(this.year, this.month - 1, 1);
      const lastDayOfMonth = new Date(this.year, this.month, 0);
      const daysInMonth = lastDayOfMonth.getDate();
      let dayOfWeek = firstDayOfMonth.getDay();
      let date = 1;

      for (let i = 0; i < 6; i++) {
        const week = [];

        for (let j = 0; j < 7; j++) {
          if (i === 0 && j < dayOfWeek) {
            week.push({ date: null });
          } else if (date > daysInMonth) {
            week.push({ date: null });
          } else {
            const today = new Date();
            const selected = this.selectedDate && this.selectedDate.getTime() === new Date(this.year, this.month - 1, date).getTime();
            week.push({ date: new Date(this.year, this.month - 1, date), today: today.getTime() === new Date(this.year, this.month - 1, date).getTime(), selected });
            date++;
          }
        }

        weeks.push(week);
      }
      return weeks.filter((e, i) => i === 5 ? !!e[0].date : true);
    },
  },
  methods: {
    prevMonth() {
      if (this.month === 1) {
        this.year--;
        this.month = 12;
      } else {
        this.month--;
      }
    },
    nextMonth() {
      if (this.month === 12) {
        this.year++;
        this.month = 1;
      } else {
        this.month++;
      }
    },
    selectDay(day) {
      if (day.date) {
        this.selectedDate = day.date;
      }
    },
  },
};
</script>

<style>
.calendar {
  font-family: Arial, sans-serif;
  width: 238px;
  margin: 0 auto;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
  height: 34px;
}
.header span {
  background-color: transparent;
  font-size: 18px;
}

.box {
  width: 100%;
  border-collapse: collapse;
  padding: 0;
}
.box-top-content {
  display: flex;
  justify-content: space-between;
}
.box-top-content > div {
  width: 34px;
  height: 34px;
  display: flex;
  justify-content: center;
  align-items: center;
}
.box-bottom {
  display: flex;
  flex-direction: column;
}
.box-bottom-content {
  display: flex;
  justify-content: space-between;
}
.box-bottom-content-box {
  width: 34px;
  height: 34px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.today {
  background-color: #eee;
}

.selected {
  background-color: #007bff;
  color: #fff;
  border-radius: 50%;
}
</style>

效果如下
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值