简介
TUI Calendar 是一个功能强大的日历组件,支持月视图、周视图、日视图,以及日程管理、拖拽等功能。本示例展示在 Vue3 中的完整集成方案。
安装依赖
npm install tui-calendar基础示例
<template>
  <div class="w-full p-4">
    <!-- 视图切换工具栏 -->
    <div
      class="flex justify-between items-center mb-5 p-4 bg-gray-50 rounded-lg shadow-sm"
    >
      <!-- 月份导航 -->
      <div class="flex items-center gap-3">
        <button
          class="flex items-center justify-center w-10 h-10 border border-gray-300 bg-white rounded-md cursor-pointer transition-all duration-300 hover:bg-gray-200 hover:border-gray-500 hover:text-gray-800"
          @click="prevMonth"
          title="上一月"
        >
          <span class="text-lg font-bold text-gray-600">‹</span>
        </button>
        <span
          class="text-lg font-bold text-gray-800 min-w-[120px] text-center"
          >{{ currentMonthText }}</span
        >
        <button
          class="flex items-center justify-center w-10 h-10 border border-gray-300 bg-white rounded-md cursor-pointer transition-all duration-300 hover:bg-gray-200 hover:border-gray-500 hover:text-gray-800"
          @click="nextMonth"
          title="下一月"
        >
          <span class="text-lg font-bold text-gray-600">›</span>
        </button>
        <button
          class="px-3 py-2 text-xs font-medium border border-gray-300 bg-white rounded-md cursor-pointer transition-all duration-300 hover:bg-gray-200 hover:border-gray-500 hover:text-gray-800 min-w-[60px]"
          @click="goToToday"
          title="今天"
        >
          今天
        </button>
      </div>
      <!-- 视图切换按钮 -->
      <div class="flex gap-3">
        <button
          class="px-4 py-2 text-sm font-medium border border-gray-300 bg-white rounded-md cursor-pointer transition-all duration-300 hover:bg-gray-200 hover:border-gray-500 hover:text-gray-800"
          :class="{
            '!bg-blue-500 !text-white !border-blue-500 hover:!bg-blue-600 hover:!border-blue-600 hover:!text-white':
              currentView === 'month',
          }"
          @click="changeView('month')"
        >
          月视图
        </button>
        <button
          class="px-4 py-2 text-sm font-medium border border-gray-300 bg-white rounded-md cursor-pointer transition-all duration-300 hover:bg-gray-200 hover:border-gray-500 hover:text-gray-800"
          :class="{
            '!bg-blue-500 !text-white !border-blue-500 hover:!bg-blue-600 hover:!border-blue-600 hover:!text-white':
              currentView === 'week',
          }"
          @click="changeView('week')"
        >
          周视图
        </button>
        <button
          class="px-4 py-2 text-sm font-medium border border-gray-300 bg-white rounded-md cursor-pointer transition-all duration-300 hover:bg-gray-200 hover:border-gray-500 hover:text-gray-800"
          :class="{
            '!bg-blue-500 !text-white !border-blue-500 hover:!bg-blue-600 hover:!border-blue-600 hover:!text-white':
              currentView === 'day',
          }"
          @click="changeView('day')"
        >
          日视图
        </button>
      </div>
    </div>
    <div
      id="calendar"
      class="w-full h-full bg-white rounded-lg shadow-sm border border-gray-200"
    ></div>
  </div>
</template>
<script>
import "tui-calendar/dist/tui-calendar.css";
import Calendar from "tui-calendar";
export default {
  data() {
    return {
      calendar: null,
      currentView: "month", // 当前视图
      currentDate: new Date(), // 当前显示的日期
      schedules: [
        {
          id: "1",
          calendarId: "work",
          title: "会议",
          category: "time",
          start: "2025-09-07T09:00:00",
          end: "2025-09-08T10:00:00",
          color: "#ff0000",
        },
        {
          id: "2",
          calendarId: "personal",
          title: "生日聚会",
          category: "milestone",
          start: "2025-09-09T18:00:00",
          end: "2025-09-11T22:00:00",
          color: "#00ff00",
        },
      ],
    };
  },
  computed: {
    // 当前月份文本
    currentMonthText() {
      const year = this.currentDate.getFullYear();
      const month = this.currentDate.getMonth() + 1;
      return `${year}年${month}月`;
    },
  },
  mounted() {
    this.initCalendar();
  },
  methods: {
    initCalendar() {
      this.calendar = new Calendar("#calendar", {
        defaultView: this.currentView,
        useCreationPopup: true,
        useDetailPopup: true,
        calendars: [
          {
            id: "work",
            name: "工作",
            color: "#ff0000",
          },
          {
            id: "personal",
            name: "个人",
            color: "#00ff00",
          },
        ],
      });
      this.calendar.createSchedules(this.schedules);
      this.bindEvents();
    },
    bindEvents() {
      this.calendar.on("clickSchedule", (e) => {
        console.log("点击日程:", e.schedule);
      });
      this.calendar.on("beforeCreateSchedule", (e) => {
        console.log("创建日程:", e);
      });
    },
    // 切换视图
    changeView(view) {
      this.currentView = view;
      this.calendar.changeView(view);
    },
    // 上一月
    prevMonth() {
      const newDate = new Date(this.currentDate);
      newDate.setMonth(newDate.getMonth() - 1);
      this.currentDate = newDate;
      this.calendar.setDate(newDate);
    },
    // 下一月
    nextMonth() {
      const newDate = new Date(this.currentDate);
      newDate.setMonth(newDate.getMonth() + 1);
      this.currentDate = newDate;
      this.calendar.setDate(newDate);
    },
    // 回到今天
    goToToday() {
      this.currentDate = new Date();
      this.calendar.setDate(new Date());
    },
    addSchedule(schedule) {
      this.calendar.createSchedules([schedule]);
    },
    updateSchedule(scheduleId, changes) {
      this.calendar.updateSchedule(scheduleId, null, changes);
    },
    deleteSchedule(scheduleId) {
      this.calendar.deleteSchedule(scheduleId);
    },
  },
};
</script>
高级配置
自定义主题
const customTheme = {
  "common.border": "1px solid #e5e5e5",
  "common.backgroundColor": "white",
  "common.holiday.color": "#ff4040",
  "common.saturday.color": "#333",
  "common.dayname.color": "#333",
  "common.today.color": "#135de6",
  "month.dayname.fontSize": "13px",
  "month.dayname.fontWeight": "bold",
  "month.schedule.fontSize": "12px",
  "month.schedule.borderRadius": "2px",
  "month.schedule.height": "18px",
};
this.calendar.setTheme(customTheme);视图切换
// 切换到月视图
this.calendar.changeView("month");
// 切换到周视图
this.calendar.changeView("week");
// 切换到日视图
this.calendar.changeView("day");日程过滤
// 按日历过滤
this.calendar.toggleSchedules("work", true);
// 按日程类型过滤
this.calendar.setCalendars([
  {
    id: "work",
    name: "工作",
    color: "#ff0000",
    visible: true,
  },
  {
    id: "personal",
    name: "个人",
    color: "#00ff00",
    visible: false,
  },
]);常见问题解决
样式冲突
/* 解决样式冲突 */
.tui-calendar {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}
/* 自定义弹窗样式 */
.tui-full-calendar-popup {
  z-index: 9999 !important;
}性能优化
// 大量日程处理
const optimizedOptions = {
  defaultView: "month",
  useCreationPopup: true,
  useDetailPopup: true,
  taskView: false, // 禁用任务视图提升性能
  scheduleView: ["time"], // 只显示时间类型日程
  calendars: [
    {
      id: "default",
      name: "默认",
      color: "#ff0000",
    },
  ],
};移动端适配
// 移动端配置
const mobileOptions = {
  defaultView: "month",
  useCreationPopup: true,
  useDetailPopup: true,
  calendars: [
    {
      id: "default",
      name: "默认",
      color: "#ff0000",
    },
  ],
  template: {
    monthDayname: (dayname) =>
      `<span class="calendar-week-dayname-name">${dayname.label}</span>`,
    monthSchedule: (schedule) =>
      `<span class="calendar-schedule-content">${schedule.title}</span>`,
  },
};总结
TUI Calendar 是一个功能强大的日历组件,主要特点包括:
- 多视图支持: 月、周、日视图
- 日程管理: 创建、编辑、删除日程
- 拖拽功能: 支持日程拖拽调整时间
- 主题定制: 支持自定义主题和样式
- 事件丰富: 提供完整的事件监听机制
- 易于集成: 与 Vue3 项目无缝集成
 原文链接:https://code.ifrontend.net/archives/1257,转载请注明出处。		    			
		             
	
评论0