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