当前位置:首页 > VUE

Vue实现日历日程

2026-01-19 07:03:56VUE

Vue 实现日历日程

使用第三方库(如 FullCalendar)

FullCalendar 是一个功能强大的日历库,支持 Vue 集成。安装依赖:

Vue实现日历日程

npm install @fullcalendar/vue @fullcalendar/core @fullcalendar/daygrid @fullcalendar/interaction

引入并配置组件:

Vue实现日历日程

<template>
  <FullCalendar :options="calendarOptions" />
</template>

<script>
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin from '@fullcalendar/interaction'

export default {
  components: { FullCalendar },
  data() {
    return {
      calendarOptions: {
        plugins: [dayGridPlugin, interactionPlugin],
        initialView: 'dayGridMonth',
        events: [
          { title: '会议', start: '2023-10-10' },
          { title: '出差', start: '2023-10-15', end: '2023-10-17' }
        ],
        dateClick: this.handleDateClick,
        eventClick: this.handleEventClick
      }
    }
  },
  methods: {
    handleDateClick(arg) {
      alert('点击日期: ' + arg.dateStr)
    },
    handleEventClick(arg) {
      alert('点击事件: ' + arg.event.title)
    }
  }
}
</script>

自定义日历组件

如果不需要复杂功能,可以手动实现基础日历。以下是一个简单示例:

<template>
  <div class="calendar">
    <div class="header">
      <button @click="prevMonth">上个月</button>
      <h3>{{ currentYear }}年{{ currentMonth + 1 }}月</h3>
      <button @click="nextMonth">下个月</button>
    </div>
    <div class="days">
      <div v-for="day in days" :key="day" class="day-header">{{ day }}</div>
    </div>
    <div class="dates">
      <div 
        v-for="date in visibleDates" 
        :key="date.date"
        :class="['date', { 'current-month': date.isCurrentMonth }]"
        @click="selectDate(date)"
      >
        {{ date.date }}
        <div v-if="hasEvent(date)" class="event-dot"></div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      days: ['日', '一', '二', '三', '四', '五', '六'],
      currentYear: new Date().getFullYear(),
      currentMonth: new Date().getMonth(),
      events: [
        { date: '2023-10-15', title: '项目会议' },
        { date: '2023-10-20', title: '团队聚餐' }
      ]
    }
  },
  computed: {
    visibleDates() {
      const dates = []
      const firstDay = new Date(this.currentYear, this.currentMonth, 1)
      const lastDay = new Date(this.currentYear, this.currentMonth + 1, 0)

      // 上个月末尾几天
      const prevMonthDays = firstDay.getDay()
      for (let i = prevMonthDays - 1; i >= 0; i--) {
        const date = new Date(this.currentYear, this.currentMonth, -i)
        dates.push({
          date: date.getDate(),
          fullDate: date,
          isCurrentMonth: false
        })
      }

      // 当前月
      for (let i = 1; i <= lastDay.getDate(); i++) {
        const date = new Date(this.currentYear, this.currentMonth, i)
        dates.push({
          date: i,
          fullDate: date,
          isCurrentMonth: true
        })
      }

      // 下个月开头几天
      const nextMonthDays = 6 - lastDay.getDay()
      for (let i = 1; i <= nextMonthDays; i++) {
        const date = new Date(this.currentYear, this.currentMonth + 1, i)
        dates.push({
          date: date.getDate(),
          fullDate: date,
          isCurrentMonth: false
        })
      }

      return dates
    }
  },
  methods: {
    prevMonth() {
      if (this.currentMonth === 0) {
        this.currentYear--
        this.currentMonth = 11
      } else {
        this.currentMonth--
      }
    },
    nextMonth() {
      if (this.currentMonth === 11) {
        this.currentYear++
        this.currentMonth = 0
      } else {
        this.currentMonth++
      }
    },
    selectDate(date) {
      if (date.isCurrentMonth) {
        console.log('选中日期:', date.fullDate)
      }
    },
    hasEvent(date) {
      if (!date.isCurrentMonth) return false
      const dateStr = date.fullDate.toISOString().split('T')[0]
      return this.events.some(event => event.date === dateStr)
    }
  }
}
</script>

<style>
.calendar {
  width: 100%;
  max-width: 600px;
  margin: 0 auto;
}
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}
.days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  text-align: center;
}
.dates {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 5px;
}
.date {
  aspect-ratio: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  border-radius: 4px;
}
.date.current-month {
  background: #f0f0f0;
}
.date:hover {
  background: #e0e0e0;
}
.event-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #f00;
  margin-top: 2px;
}
</style>

功能扩展建议

  1. 添加事件表单:点击日期弹出表单,允许用户添加/编辑日程
  2. 持久化存储:将日程数据保存到 localStorage 或后端数据库
  3. 周视图切换:支持按月/周/日不同维度查看日程
  4. 拖拽功能:实现事件拖拽调整时间
  5. 颜色分类:为不同类型的事件设置不同颜色标识

两种方案各有优劣:第三方库功能全面但体积较大;自定义组件更轻量但需要手动实现更多功能。可根据项目需求选择合适方案。

标签: 日程日历
分享给朋友:

相关文章

vue 实现日历

vue 实现日历

实现基础日历结构 使用 Vue 的模板语法构建日历的网格布局,通常以 7 列(一周)和 5-6 行(月份天数)的表格形式展示。通过 v-for 循环渲染日期单元格,动态绑定样式和事件。…

vue实现每日签到日历

vue实现每日签到日历

实现每日签到日历的基本思路 使用Vue实现每日签到日历需要结合日期处理和组件化设计。核心功能包括生成当月日历数据、标记签到状态以及交互逻辑。 日历数据生成 通过JavaScript的Date对象处理…

vue滚动实现日历组件

vue滚动实现日历组件

实现思路 基于Vue实现滚动日历组件的核心在于动态生成日期数据,并通过CSS和触摸事件实现平滑滚动效果。关键在于处理日期计算、渲染优化和交互逻辑。 基础结构设计 <template>…

vue实现值班日历

vue实现值班日历

Vue 实现值班日历的方法 使用 FullCalendar 插件 FullCalendar 是一个功能强大的日历插件,支持 Vue 集成。安装依赖: npm install @fullcal…

php实现日历

php实现日历

PHP 实现日历的方法 PHP 可以用于生成动态日历,以下是几种常见的实现方式: 使用 date 和 mktime 函数 通过 PHP 内置的日期和时间函数,可以计算月份的天数和起始星期几。…

js日历案例实现

js日历案例实现

实现基础日历功能 日历功能可以通过JavaScript结合HTML和CSS实现,核心是动态生成日期表格。以下代码展示了一个基础的日历生成器: function generateCalendar(ye…