当前位置:首页 > VUE

vue 实现日历

2026-02-10 07:13:56VUE

Vue 日历组件实现

基础日历结构

使用 Vue 的模板和数据绑定功能创建日历骨架。需要定义当前年份、月份,并生成对应的日期数组。

<template>
  <div class="calendar">
    <div class="header">
      <button @click="prevMonth">上一月</button>
      <h2>{{ currentYear }}年{{ currentMonth + 1 }}月</h2>
      <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="(day, index) in days" 
        :key="index"
        :class="{ 'other-month': !day.isCurrentMonth }"
      >
        {{ day.date }}
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      weekdays: ['日', '一', '二', '三', '四', '五', '六'],
      currentYear: new Date().getFullYear(),
      currentMonth: new Date().getMonth(),
    }
  },
  computed: {
    days() {
      // 生成当月日期数组的逻辑
    }
  },
  methods: {
    prevMonth() {
      // 上个月逻辑
    },
    nextMonth() {
      // 下个月逻辑
    }
  }
}
</script>

<style>
.calendar {
  width: 100%;
  max-width: 600px;
  margin: 0 auto;
}
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.weekdays, .days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
}
.days div {
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.other-month {
  color: #ccc;
}
</style>

日期生成逻辑

在 computed 属性中完善 days 计算逻辑,生成包含当月日期及前后月份补全的日期数组。

computed: {
  days() {
    const firstDay = new Date(this.currentYear, this.currentMonth, 1)
    const lastDay = new Date(this.currentYear, this.currentMonth + 1, 0)
    const daysInMonth = lastDay.getDate()
    const firstDayOfWeek = firstDay.getDay()

    const days = []

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

    // 添加当月所有日期
    for (let i = 1; i <= daysInMonth; i++) {
      days.push({
        date: i,
        isCurrentMonth: true
      })
    }

    // 添加下个月开始的几天
    const totalCells = prevMonthDays + daysInMonth
    const nextMonthDays = totalCells <= 35 ? 35 - totalCells : 42 - totalCells
    for (let i = 1; i <= nextMonthDays; i++) {
      days.push({
        date: i,
        isCurrentMonth: false
      })
    }

    return days
  }
}

月份切换功能

实现月份切换方法,确保年份也会相应变化。

methods: {
  prevMonth() {
    if (this.currentMonth === 0) {
      this.currentMonth = 11
      this.currentYear--
    } else {
      this.currentMonth--
    }
  },
  nextMonth() {
    if (this.currentMonth === 11) {
      this.currentMonth = 0
      this.currentYear++
    } else {
      this.currentMonth++
    }
  }
}

日期选择功能

添加日期选择功能,记录选中的日期并高亮显示。

<div 
  v-for="(day, index) in days" 
  :key="index"
  :class="{ 
    'other-month': !day.isCurrentMonth,
    'selected': isSelected(day)
  }"
  @click="selectDate(day)"
>
  {{ day.date }}
</div>
data() {
  return {
    // 其他数据...
    selectedDate: null
  }
},
methods: {
  selectDate(day) {
    if (day.isCurrentMonth) {
      this.selectedDate = new Date(this.currentYear, this.currentMonth, day.date)
    }
  },
  isSelected(day) {
    if (!this.selectedDate || !day.isCurrentMonth) return false
    return this.selectedDate.getDate() === day.date && 
           this.selectedDate.getMonth() === this.currentMonth && 
           this.selectedDate.getFullYear() === this.currentYear
  }
}
.selected {
  background-color: #42b983;
  color: white;
  border-radius: 50%;
}

高级功能扩展

可以进一步扩展日历组件功能:

  1. 添加事件标记功能,在特定日期显示标记点
  2. 实现范围选择,允许选择开始和结束日期
  3. 添加周视图切换功能
  4. 集成日期选择器弹出框
  5. 支持多语言和本地化设置
// 事件标记示例
data() {
  return {
    events: {
      '2023-11-15': '会议',
      '2023-11-20': '生日'
    }
  }
},
methods: {
  hasEvent(day) {
    if (!day.isCurrentMonth) return false
    const dateStr = `${this.currentYear}-${this.currentMonth + 1}-${day.date}`
    return this.events[dateStr]
  }
}
<div class="day-cell" @click="selectDate(day)">
  {{ day.date }}
  <div v-if="hasEvent(day)" class="event-dot"></div>
</div>
.event-dot {
  width: 6px;
  height: 6px;
  background-color: #f00;
  border-radius: 50%;
  position: absolute;
  bottom: 5px;
  left: 50%;
  transform: translateX(-50%);
}

vue 实现日历

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

相关文章

vue按钮实现截屏

vue按钮实现截屏

Vue 按钮实现截屏的方法 在 Vue 项目中实现截屏功能可以通过多种方式完成,以下是几种常见的方法: 使用 html2canvas 库 安装 html2canvas 库: npm ins…

vue设计与实现下载

vue设计与实现下载

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

vue实现截图

vue实现截图

Vue 实现截图的方法 使用 html2canvas 库 安装 html2canvas 库: npm install html2canvas 在 Vue 组件中使用: import html2ca…

vue实现setinterval

vue实现setinterval

在 Vue 中使用 setInterval Vue 中可以通过生命周期钩子和方法结合 setInterval 实现定时任务。以下是一个完整的实现示例: <template> <…

vue实现翻译

vue实现翻译

Vue 实现翻译功能的方法 使用 i18n 插件实现多语言切换 安装 vue-i18n 插件: npm install vue-i18n 创建语言资源文件(如 en.json 和 zh.json):…

vue 实现流程

vue 实现流程

Vue 实现流程 Vue.js 是一个渐进式 JavaScript 框架,用于构建用户界面。以下是 Vue 实现的基本流程: 安装 Vue.js 通过 CDN 引入或使用 npm/yarn 安装:…