当前位置:首页 > VUE

vue3实现日历

2026-02-21 09:09:01VUE

Vue3 实现日历组件

使用 Vue3 的 Composition API 和 <script setup> 语法实现一个基础日历组件。以下代码展示核心功能:日期渲染、月份切换和日期选择。

模板部分

vue3实现日历

<template>
  <div class="calendar">
    <div class="header">
      <button @click="prevMonth">←</button>
      <h2>{{ currentMonth }}</h2>
      <button @click="nextMonth">→</button>
    </div>
    <div class="weekdays">
      <div v-for="day in weekdays" :key="day" class="weekday">{{ day }}</div>
    </div>
    <div class="days">
      <div 
        v-for="day in daysInMonth" 
        :key="day.date"
        :class="{ 
          'day': true,
          'selected': day.date === selectedDate,
          'other-month': !day.isCurrentMonth
        }"
        @click="selectDate(day.date)"
      >
        {{ day.day }}
      </div>
    </div>
  </div>
</template>

逻辑部分

<script setup>
import { ref, computed } from 'vue';

const currentDate = ref(new Date());
const selectedDate = ref(null);

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

const currentMonth = computed(() => {
  return currentDate.value.toLocaleString('zh-CN', { 
    year: 'numeric', 
    month: 'long' 
  });
});

const daysInMonth = computed(() => {
  const year = currentDate.value.getFullYear();
  const month = currentDate.value.getMonth();

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

  // 获取当月天数
  const days = [];
  for (let i = 1; i <= lastDay.getDate(); i++) {
    days.push({
      day: i,
      date: new Date(year, month, i).toDateString(),
      isCurrentMonth: true
    });
  }

  // 补充上个月末尾几天
  const prevMonthDays = firstDay.getDay();
  const prevMonthLastDay = new Date(year, month, 0).getDate();
  for (let i = 0; i < prevMonthDays; i++) {
    days.unshift({
      day: prevMonthLastDay - i,
      date: new Date(year, month - 1, prevMonthLastDay - i).toDateString(),
      isCurrentMonth: false
    });
  }

  // 补充下个月开头几天
  const nextMonthDays = 6 - lastDay.getDay();
  for (let i = 1; i <= nextMonthDays; i++) {
    days.push({
      day: i,
      date: new Date(year, month + 1, i).toDateString(),
      isCurrentMonth: false
    });
  }

  return days;
});

function prevMonth() {
  currentDate.value = new Date(
    currentDate.value.getFullYear(),
    currentDate.value.getMonth() - 1,
    1
  );
}

function nextMonth() {
  currentDate.value = new Date(
    currentDate.value.getFullYear(),
    currentDate.value.getMonth() + 1,
    1
  );
}

function selectDate(date) {
  selectedDate.value = date;
}
</script>

样式部分

vue3实现日历

<style scoped>
.calendar {
  width: 300px;
  border: 1px solid #eee;
  border-radius: 8px;
  padding: 10px;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  text-align: center;
  font-weight: bold;
  margin-bottom: 5px;
}

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

.day {
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  border-radius: 4px;
}

.day:hover {
  background-color: #f0f0f0;
}

.selected {
  background-color: #1890ff;
  color: white;
}

.other-month {
  color: #ccc;
}
</style>

功能扩展建议

  1. 日期范围选择
    
    const rangeStart = ref(null);
    const rangeEnd = ref(null);

function selectDate(date) { if (!rangeStart.value || rangeEnd.value) { rangeStart.value = date; rangeEnd.value = null; } else if (date > rangeStart.value) { rangeEnd.value = date; } else { rangeEnd.value = rangeStart.value; rangeStart.value = date; } }


2. 添加事件标记
```vue
const events = ref({
  'Wed May 15 2024': '会议',
  'Fri May 17 2024': '生日'
});

// 在模板中添加事件显示
<div v-if="events[day.date]" class="event-marker"></div>
  1. 国际化支持
    import { useI18n } from 'vue-i18n';
    // 在setup中
    const { t } = useI18n();
    // 替换weekdays为翻译后的版本

性能优化

对于大型日历应用,考虑使用虚拟滚动技术处理大量日期渲染:

import { useVirtualList } from '@vueuse/core';

const { list, containerProps, wrapperProps } = useVirtualList(
  daysInMonth,
  { itemHeight: 30 }
);

以上实现提供了日历的核心功能,可根据实际需求进一步扩展和完善。

标签: 日历
分享给朋友:

相关文章

vue实现日历

vue实现日历

Vue 实现日历组件 使用 Vue 实现日历组件可以通过自定义开发或借助第三方库完成。以下是两种常见方法: 方法一:自定义日历组件 创建基础日历结构,利用 Vue 的响应式特性动态渲染日期。核心逻…

vue 日历组件实现

vue 日历组件实现

Vue 日历组件实现 基本结构搭建 使用Vue的单文件组件(SFC)结构,创建一个基础的日历组件框架。需要定义月份、年份的状态管理,以及日期渲染逻辑。 <template> <…

vue如何实现日历

vue如何实现日历

使用第三方库(如 FullCalendar) FullCalendar 是一个功能强大的日历库,支持 Vue 集成。安装依赖后,通过组件的方式引入日历功能。配置事件、日期范围和交互逻辑可以通过 pro…

vue实现每日签到日历

vue实现每日签到日历

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

vue实现全年日历功能

vue实现全年日历功能

实现全年日历功能 在Vue中实现全年日历功能,可以通过组合多个月份日历组件或使用第三方库来简化开发。以下是两种常见方法: 使用第三方库(如FullCalendar) 安装FullCalendar…

vue滚动实现日历组件

vue滚动实现日历组件

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