当前位置:首页 > VUE

vue实现mac日历

2026-01-17 10:11:50VUE

Vue 实现 Mac 日历功能

要在 Vue 中实现类似 Mac 日历的功能,可以结合第三方库或自定义组件开发。以下是两种常见方法:

使用 FullCalendar 库

FullCalendar 是一个功能强大的日历库,支持月视图、周视图和日视图,类似 Mac 日历的布局。

vue实现mac日历

安装 FullCalendar:

vue实现mac日历

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

示例代码:

<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',
        headerToolbar: {
          left: 'prev,next today',
          center: 'title',
          right: 'dayGridMonth,dayGridWeek,dayGridDay'
        },
        events: [
          { title: 'Meeting', start: new Date() }
        ],
        dateClick: this.handleDateClick,
        eventClick: this.handleEventClick
      }
    }
  },
  methods: {
    handleDateClick(arg) {
      alert('Date clicked: ' + arg.dateStr)
    },
    handleEventClick(arg) {
      alert('Event clicked: ' + arg.event.title)
    }
  }
}
</script>

自定义日历组件

如果需要更贴近 Mac 风格的设计,可以自定义实现:

<template>
  <div class="mac-calendar">
    <div class="calendar-header">
      <button @click="prevMonth">←</button>
      <h3>{{ currentMonth }}</h3>
      <button @click="nextMonth">→</button>
    </div>
    <div class="calendar-grid">
      <div v-for="day in days" :key="day" class="day-header">
        {{ day }}
      </div>
      <div 
        v-for="date in visibleDates" 
        :key="date.toISOString()"
        :class="['date-cell', { 'current-month': isCurrentMonth(date) }]"
        @click="selectDate(date)"
      >
        {{ date.getDate() }}
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      currentDate: new Date(),
      days: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
    }
  },
  computed: {
    currentMonth() {
      return this.currentDate.toLocaleString('default', { month: 'long', year: 'numeric' })
    },
    visibleDates() {
      const start = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth(), 1)
      const end = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth() + 1, 0)

      // 获取当月第一天是星期几
      const startDay = start.getDay()
      // 获取当月最后一天是星期几
      const endDay = end.getDay()

      // 计算需要显示的上个月和下个月的日期
      const prevMonthDays = startDay
      const nextMonthDays = 6 - endDay

      const dates = []

      // 添加上个月的日期
      for (let i = prevMonthDays; i > 0; i--) {
        const date = new Date(start)
        date.setDate(-i + 1)
        dates.push(date)
      }

      // 添加当月的日期
      for (let i = 1; i <= end.getDate(); i++) {
        const date = new Date(start)
        date.setDate(i)
        dates.push(date)
      }

      // 添加下个月的日期
      for (let i = 1; i <= nextMonthDays; i++) {
        const date = new Date(end)
        date.setDate(end.getDate() + i)
        dates.push(date)
      }

      return dates
    }
  },
  methods: {
    isCurrentMonth(date) {
      return date.getMonth() === this.currentDate.getMonth()
    },
    prevMonth() {
      this.currentDate = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth() - 1, 1)
    },
    nextMonth() {
      this.currentDate = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth() + 1, 1)
    },
    selectDate(date) {
      this.$emit('date-selected', date)
    }
  }
}
</script>

<style>
.mac-calendar {
  font-family: -apple-system, BlinkMacSystemFont, sans-serif;
  width: 300px;
  border-radius: 10px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  overflow: hidden;
}

.calendar-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px;
  background-color: #f0f0f0;
}

.calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 5px;
  padding: 10px;
}

.day-header {
  text-align: center;
  font-weight: bold;
  padding: 5px;
}

.date-cell {
  text-align: center;
  padding: 8px;
  border-radius: 5px;
  cursor: pointer;
}

.date-cell:hover {
  background-color: #e0e0e0;
}

.current-month {
  background-color: #fff;
}

.date-cell:not(.current-month) {
  color: #aaa;
}
</style>

功能增强建议

  1. 添加事件管理功能,允许用户在特定日期添加/编辑事件
  2. 实现拖放功能,允许通过拖放调整事件时间
  3. 添加周视图和日视图切换
  4. 集成提醒功能,类似Mac日历的提醒系统
  5. 添加日历订阅功能,支持iCal格式

这两种方法都能实现类似Mac日历的功能,FullCalendar提供了更多开箱即用的功能,而自定义组件则提供了更大的灵活性和样式控制权。

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

相关文章

vue实现适老化样式

vue实现适老化样式

Vue 实现适老化样式的关键方法 全局字体与字号调整 通过 CSS 变量或主题配置统一放大基础字号,建议正文不小于 18px,标题更大。在 App.vue 中设置全局样式: :root { -…

vue表格重置怎么实现

vue表格重置怎么实现

重置表格数据的方法 在Vue中重置表格数据通常需要操作绑定的数据源,以下是几种常见实现方式: 直接重置数据源 // 假设表格绑定的是tableData this.tableData = [...t…

vue实现导航切换内容

vue实现导航切换内容

Vue实现导航切换内容的方法 在Vue中实现导航切换内容,可以通过以下方式实现: 使用动态组件 动态组件通过<component :is="currentComponent">实现内容切…

vue设计与实现下载

vue设计与实现下载

vue设计与实现电子书下载 《Vue.js设计与实现》是一本深入解析Vue.js框架原理的书籍,由霍春阳(HcySunYang)撰写。以下是获取该资源的常见途径: 正版购买渠道 京东、当当、天…

vue中实现显示和隐藏

vue中实现显示和隐藏

控制显示与隐藏的方法 在Vue中实现元素的显示和隐藏可以通过多种方式完成,以下是常见的几种方法: 1. 使用v-if指令v-if根据条件动态添加或移除DOM元素,适合需要频繁切换的场景。当条件为fa…

vue实现选中单元格

vue实现选中单元格

Vue 实现选中单元格的方法 基础实现思路 在 Vue 中实现选中单元格功能,通常可以通过动态绑定 class 或 style 来实现。以下是一个基于表格的简单实现示例: <template…