likes
comments
collection
share

Vue3+Vite 实现一个日历日程表日程

作者站长头像
站长
· 阅读数 3

类似如图的日历,可以翻页,定位今日。

Vue3+Vite 实现一个日历日程表日程

首先写一个获取某日期所有信息的方法(年、月、日、周几。。。)

export function dateObject(date=new Date()) {
  const year = date.getFullYear()
  const fullMonth = date.getMonth() + 1 < 10 ? `0${date.getMonth() + 1}` : date.getMonth() + 1
  const month = date.getMonth() + 1
  const fullDay = date.getDate() < 10 ? `0${date.getDate()}` : date.getDate()
  const day = date.getDate()
  const time = date.getTime()
  const weekday = date.gettDay()
  return {
      year: year,
      month: month,
      fullMonth: fullMonth,
      day: day,
      fullDay: fullDay,
      time: time,
      weekday: weekday
  }
}

获取某月份有几天

function getDays(year, month) {
  // 0:代表上月最后一天。这里month,不需要 - 1,传入的时候本身就 + 1.
  return new Date(year, month, 0).getDate()
}

创建日历列表

const now = dateObject()
const current = ref({
    year: now.year,
    month: now.month
})
const monthDays = ref([0, 0, 0])
const calendar = ref([])
const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
/**
 * @description: 更新上月、本月、下月总天数
 */
function updateMonthDays() {
  monthDays.value[0] = getDays(calendarObj.value.year, calendarObj.value.month - 1)
  monthDays.value[1] = getDays(calendarObj.value.year, calendarObj.value.month)
  monthDays.value[2] = getDays(calendarObj.value.year, calendarObj.value.month + 1)
}
/**
 * @description:创建日历列表
 */
function createDaysList() {
    const first = new Date(current.value.year, current.value.month - 1, day).getDay()
    const last = new Date(current.value.year, current.value.month - 1, day).getDay()
    const calendarDays = monthDays.value[1] + first + (7 - last)
    const weekNum = Math.floor(calendarDays / 7)
    const _calendar = []
    for (let i = 0; i < weekNum; i++) {
        _calendar.push([])
    }
    for (let i = 0; i < calendarDays - 1; i++) {
        const index = Math.floor(i / 7)
        if (i < first) {
          _calendar[index][i % 7] = {
            ...dateObject(current.value.year, current.value.month, (i - first + 1)),
            week: index
          }
        } else if (i > monthDays.value[1] + first) {
          _calendar[index][i % 7] = {
            ...dateObject(current.value.year, current.value.month + 1, (i - monthDays.value[1])),
            week: index
          }
        } else {
          _calendar[index][i % 7] = {
            ...dateObject(current.value.year, current.value.month, (i - first + 1)),
            week: index,
          }
        }
    }
  calendar.value = _calendar
}

updateMonthDays()
createDaysList()

翻页、定位今日月份

/**
 * @description: 获取上月、本月、下月日历信息
 */
function getMonth(type) {
  switch (type) {
    case 'last':
      if (current.value.month === 1) {
        current.value.year--
        current.value.month = 12
      } else {
        current.value.month--
      }
      break
    case 'next':
      if (current.value.month === 12) {
        current.value.year++
        current.value.month = 1
      } else {
        current.value.month++
      }
      break
    case 'today':
      current.value.year = now.year
      current.value.month = now.month
      break
    default:
      break
  }
}

html部分

    <el-row type="flex" justify="space-between">
      <el-col :span="12" style="font-size: 20px;font-weight: 700;">{{ current.year }} 年 {{ current.month
        }} 月</el-col>
      <el-col :span="12" style="text-align: end;">
        <el-button icon="ArrowLeft" size="small" @click="getMonth('last')" />
        <el-button size="small" @click="getMonth('today')">今天</el-button>
        <el-button size="small" icon="ArrowRight" @click="getMonth('next')" />
      </el-col>
    </el-row>
    <el-row type="flex">
      <div class="weekday" v-for="(day, key) in weekdays" :key="key">{{ day }}</div>
    </el-row>
    <el-row
      v-for="(week, weekIndex) in calendar"
      :key="weekIndex"
      type="flex"
    >
      <div
        v-for="(day, index) in week"
        :key="index"
        class="weekday day"
        :class="index === 0 || index === 6 ? 'weekend' : ''"
      >
        <div style="height: 100%">
          <el-row type="flex">
            <el-col :span="12" style="text-align: start"></el-col>
            <el-col :span="12">
              <span :class="isToday(item, now)">{{ item.day }}</span>
            </el-col>
          </el-row>
          // ...
        </div>
      </div>
    </el-row>

css部分

.weekday {
  flex: 1;
  text-align: end;
  color: #898989;
  padding: 8px 0;
}
.weekend {
  background-color: #eee;
}

.day {
  border: 1px solid #e7e7e7;
  margin: 0px -1px -1px 0px;
  padding: 8px;
  height: 120px;
}
.today {
  border-radius: 50%;
  background-color: red;
  display: inline-block;
  padding: 2px 4px;
  color: #fff;
}

效果图: Vue3+Vite 实现一个日历日程表日程

点击添加日程的功能还在写,有空再更新。。。