当前位置:首页 > VUE

vue VUE实现日历组件功能

2026-03-07 17:12:22VUE

实现日历组件的基本思路

日历组件的核心是动态生成日期表格,并处理用户交互(如点击日期、切换月份)。Vue的响应式数据和组件化特性非常适合实现这一功能。

核心代码实现

模板部分(Calendar.vue)

<template>
  <div class="calendar">
    <div class="header">
      <button @click="prevMonth">上个月</button>
      <span>{{ currentYear }}年{{ currentMonth + 1 }}月</span>
      <button @click="nextMonth">下个月</button>
    </div>
    <div class="weekdays">
      <div v-for="day in weekdays" :key="day">{{ day }}</div>
    </div>
    <div class="days">
      <div 
        v-for="(date, index) in days" 
        :key="index"
        :class="{ 
          'other-month': !date.isCurrentMonth,
          'today': date.isToday,
          'selected': date.isSelected
        }"
        @click="selectDate(date)"
      >
        {{ date.day }}
      </div>
    </div>
  </div>
</template>

脚本部分

<script>
export default {
  data() {
    return {
      weekdays: ['日', '一', '二', '三', '四', '五', '六'],
      currentDate: new Date(),
      selectedDate: null
    }
  },
  computed: {
    currentYear() {
      return this.currentDate.getFullYear()
    },
    currentMonth() {
      return this.currentDate.getMonth()
    },
    days() {
      const year = this.currentYear
      const month = this.currentMonth

      // 获取当月第一天和最后一天
      const firstDay = new Date(year, month, 1)
      const lastDay = new Date(year, month + 1, 0)

      // 获取当月天数
      const daysInMonth = lastDay.getDate()

      // 获取第一天是星期几
      const firstDayOfWeek = firstDay.getDay()

      // 生成日期数组
      const days = []

      // 添加上个月末尾的几天
      const prevMonthLastDay = new Date(year, month, 0).getDate()
      for (let i = 0; i < firstDayOfWeek; i++) {
        days.push({
          day: prevMonthLastDay - firstDayOfWeek + i + 1,
          isCurrentMonth: false,
          date: new Date(year, month - 1, prevMonthLastDay - firstDayOfWeek + i + 1)
        })
      }

      // 添加当月日期
      const today = new Date()
      for (let i = 1; i <= daysInMonth; i++) {
        const date = new Date(year, month, i)
        days.push({
          day: i,
          isCurrentMonth: true,
          isToday: date.getDate() === today.getDate() && 
                   date.getMonth() === today.getMonth() && 
                   date.getFullYear() === today.getFullYear(),
          isSelected: this.selectedDate && 
                      date.getDate() === this.selectedDate.getDate() && 
                      date.getMonth() === this.selectedDate.getMonth() && 
                      date.getFullYear() === this.selectedDate.getFullYear(),
          date: date
        })
      }

      // 添加下个月开始的几天
      const daysNeeded = 42 - days.length // 6行x7列
      for (let i = 1; i <= daysNeeded; i++) {
        days.push({
          day: i,
          isCurrentMonth: false,
          date: new Date(year, month + 1, i)
        })
      }

      return days
    }
  },
  methods: {
    prevMonth() {
      this.currentDate = new Date(this.currentYear, this.currentMonth - 1, 1)
    },
    nextMonth() {
      this.currentDate = new Date(this.currentYear, this.currentMonth + 1, 1)
    },
    selectDate(date) {
      this.selectedDate = date.date
      this.$emit('date-selected', date.date)
    }
  }
}
</script>

样式部分

vue VUE实现日历组件功能

<style scoped>
.calendar {
  width: 300px;
  font-family: Arial, sans-serif;
}
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}
.weekdays, .days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 5px;
}
.weekdays div {
  text-align: center;
  font-weight: bold;
}
.days div {
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  border-radius: 50%;
}
.days div:hover {
  background-color: #eee;
}
.other-month {
  color: #ccc;
}
.today {
  background-color: #e6f7ff;
  font-weight: bold;
}
.selected {
  background-color: #1890ff;
  color: white;
}
</style>

功能扩展建议

  1. 多语言支持 添加i18n支持,可切换不同语言的星期显示。

  2. 日期范围选择 修改逻辑支持选择开始日期和结束日期。

    vue VUE实现日历组件功能

  3. 事件标记 允许在特定日期上显示标记点或自定义内容。

  4. 禁用日期 添加逻辑禁用不可选的日期(如过去的日期)。

  5. 自定义样式 通过props暴露更多样式定制选项。

使用示例

<template>
  <div>
    <Calendar @date-selected="handleDateSelected" />
    <p v-if="selectedDate">选中的日期: {{ selectedDate.toLocaleDateString() }}</p>
  </div>
</template>

<script>
import Calendar from './Calendar.vue'

export default {
  components: {
    Calendar
  },
  data() {
    return {
      selectedDate: null
    }
  },
  methods: {
    handleDateSelected(date) {
      this.selectedDate = date
    }
  }
}
</script>

这个实现提供了基本的日历功能,包括月份切换、日期选择和当天高亮。根据具体需求可以进一步扩展功能。

标签: 组件日历
分享给朋友:

相关文章

实现vue组件

实现vue组件

Vue 组件的基本实现 Vue 组件是 Vue.js 的核心特性之一,允许将 UI 拆分为独立、可复用的模块。以下是实现 Vue 组件的几种方式: 单文件组件 (SFC) 使用 .vue 文件格式,…

vue组件的实现

vue组件的实现

Vue 组件的实现方式 Vue 组件可以通过多种方式实现,主要包括单文件组件(SFC)、全局注册和局部注册。以下是常见的实现方法: 单文件组件(SFC) 单文件组件是 Vue 最推荐的组件化开发方式…

vue日历表格实现

vue日历表格实现

实现Vue日历表格的基本步骤 使用Vue实现日历表格需要处理日期数据生成、渲染和交互逻辑。以下是核心实现方法: 安装依赖(可选) 若需复杂功能可引入date-fns或dayjs等日期库: npm…

vue实现倒计时组件

vue实现倒计时组件

Vue 倒计时组件实现 核心思路 通过 setInterval 或 setTimeout 实现时间递减,结合 Vue 的响应式数据更新 UI。需注意组件销毁时清除定时器。 基础实现方案 模板部分…

vue组件实现

vue组件实现

Vue 组件实现 Vue 组件是 Vue.js 的核心特性之一,允许开发者将 UI 拆分为独立、可复用的模块。以下是实现 Vue 组件的几种常见方式: 单文件组件(SFC) 单文件组件是 Vue 中…

vue实现组件

vue实现组件

Vue 实现组件的方法 Vue 中实现组件可以通过多种方式,包括全局注册、局部注册、单文件组件(SFC)等。以下是常见的实现方法。 全局注册组件 全局注册的组件可以在任何 Vue 实例或组件中使用。…