Skip to content

日期选择器 ​

2023-07-20 16:57:28

在掘进上看到神光佬的一篇文章 链接,使用Date的API来实现一个日期选择器,佬用react实现,自己用vue写了下,实现了下基本的功能

当前日期为 2026年 10月 3日
2026 年 十月
日
一
二
三
四
五
六
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<script setup>
import { ref, watch, watchEffect } from 'vue'

const date = ref(new Date())
const emptyDays = ref([])
const days = ref([])
const selectedDay = ref(date.value.getDate())

const month = [
  '一月',
  '二月',
  '三月',
  '四月',
  '五月',
  '六月',
  '七月',
  '八月',
  '九月',
  '十月',
  '十一月',
  '十二月'
]

const weeks = ['日', '一', '二', '三', '四', '五', '六']

const preMonth = () => {
  date.value = new Date(date.value.getFullYear(), date.value.getMonth() - 1)
  renderDays()
}
const nextMonth = () => {
  date.value = new Date(date.value.getFullYear(), date.value.getMonth() + 1)
  renderDays()
}

const renderDays = () => {
  // 每次执行前清空
  emptyDays.value = []
  days.value = []

  // 求每个月的第一天
  const firstDay = new Date(
    date.value.getFullYear(),
    date.value.getMonth(),
    1
  ).getDay()

  // 每个月的天数
  const daysCount = new Date(
    date.value.getFullYear(),
    date.value.getMonth() + 1,
    0
  ).getDate()

  for (let i = 0; i < firstDay; i++) {
    emptyDays.value.push(i)
  }

  for (let i = 0; i < daysCount; i++) {
    days.value.push(i + 1)
  }
}

const clickDay = e => {
  selectedDay.value = Number(e.target.innerText)
}

watch(selectedDay, () => {
  console.log('日期改变了')
})

renderDays()
</script>
<template>
  <div>
    当前日期为 {{ date.getFullYear() }}年 {{ date.getMonth() + 1 }}月
    {{ selectedDay }}日
  </div>
  <div class="calendar">
    <div class="header">
      <button @click="preMonth">&lt;</button>
      <div>{{ date.getFullYear() }} 年 {{ month[date.getMonth()] }}</div>
      <button @click="nextMonth">&gt;</button>
    </div>
    <div class="days">
      <div v-for="item in weeks" class="week">{{ item }}</div>
      <div v-for="item in emptyDays" class="empty"></div>
      <div v-for="item in days" class="day">
        <template v-if="item === selectedDay">
          <div class="selected">{{ item }}</div>
        </template>
        <div v-else @click="clickDay">{{ item }}</div>
      </div>
    </div>
  </div>
</template>
<style scoped>
.calendar {
  border: 1px solid;
  padding: 10px;
  width: 300px;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 40px;
}

.days {
  display: flex;
  flex-wrap: wrap;
}

.empty,
.week,
.day {
  width: calc(100% / 7);
  text-align: center;
  line-height: 30px;
}

.day:hover,
.selected {
  background-color: #ccc;
  color: black;
  cursor: pointer;
}
</style>

Released under the MIT License.