当前位置:首页 > VUE

vue3实现日历

2026-02-21 09:09:01VUE

Vue3 实现日历组件

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

模板部分

<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>

样式部分

<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为翻译后的版本

性能优化

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

vue3实现日历

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

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

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

标签: 日历
分享给朋友:

相关文章

vue怎么实现日历

vue怎么实现日历

实现日历组件的基本方法 使用Vue实现日历组件可以通过以下步骤完成。这里提供一个基础的实现思路,结合Vue 3的Composition API和模板语法。 安装依赖(如需要) npm instal…

vue实现日历

vue实现日历

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

基于vue实现日历

基于vue实现日历

实现基础日历结构 使用Vue的模板语法构建日历的HTML结构,通常包含星期标题和日期格子。月份切换按钮通过v-on绑定事件。 <template> <div class="ca…

vue实现值班日历

vue实现值班日历

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

react实现日历插件

react实现日历插件

实现日历插件的核心步骤 安装依赖 使用react-datepicker或@mui/x-date-pickers等现成库快速实现日历功能。例如: npm install react-datepicke…

css日历制作

css日历制作

CSS日历制作方法 使用HTML和CSS创建一个简单的日历布局,可以通过以下方式实现: HTML结构 <div class="calendar"> <div class="m…