Skip to content

Calendar 日历

用于展示日期、日程管理、签到等场景的日历组件,支持日、周、月、年四种视图模式。

基础用法

最简单的日历使用方式。

2025年11月
26
27
28
29重阳节
30
31
1
2
3
4
5
6
7立冬
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22小雪
23
24
25
26
27
28
29
30
1
2
3
4
5
6
vue
<template>
  <ExCalendar v-model="selectedDate" />
</template>

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

const selectedDate = ref(new Date());
</script>

视图模式

日历支持四种视图模式:日视图、周视图、月视图(默认)和年视图。

2025年11月
26
27
28
29重阳节
30
31
1
2
3
4
5
6
7立冬
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22小雪
23
24
25
26
27
28
29
30
1
2
3
4
5
6
vue
<template>
  <ExCalendar v-model="selectedDate" :mode="mode" @mode-change="handleModeChange" />
</template>

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

const selectedDate = ref(new Date());
const mode = ref('month');

const handleModeChange = (newMode) => {
  mode.value = newMode;
  console.log('视图模式切换:', newMode);
};
</script>

日视图

日视图显示单日的详细信息和事件列表。

2025年11月26日
暂无事件
vue
<template>
  <ExCalendar v-model="selectedDate" mode="day" :events="events" />
</template>

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

const selectedDate = ref(new Date());
const events = ref([
  {
    id: 1,
    title: '团队会议',
    date: new Date(),
    type: 'primary',
    description: '讨论Q1计划',
  },
]);
</script>

周视图

周视图显示一周的日期和事件。

2025年11月第48周
23
24
25
26
27
28
29
vue
<template>
  <ExCalendar v-model="selectedDate" mode="week" :events="events" />
</template>

月视图

月视图是默认视图,显示整月的日期和事件。

2025年11月
26
27
28
29重阳节
30
31
1
2
3
4
5
6
7立冬
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22小雪
23
24
25
26
27
28
29
30
1
2
3
4
5
6
vue
<template>
  <ExCalendar v-model="selectedDate" mode="month" :events="events" />
</template>

年视图

年视图显示全年12个月的概览。

2025年
1月
12345678910111213141516171819202122232425262728293031
2月
12345678910111213141516171819202122232425262728
3月
12345678910111213141516171819202122232425262728293031
4月
123456789101112131415161718192021222324252627282930
5月
12345678910111213141516171819202122232425262728293031
6月
123456789101112131415161718192021222324252627282930
7月
12345678910111213141516171819202122232425262728293031
8月
12345678910111213141516171819202122232425262728293031
9月
123456789101112131415161718192021222324252627282930
10月
12345678910111213141516171819202122232425262728293031
11月
123456789101112131415161718192021222324252627282930
12月
12345678910111213141516171819202122232425262728293031
vue
<template>
  <ExCalendar v-model="selectedDate" mode="year" />
</template>

显示事件

可以在日历上显示事件,支持不同类型的事件样式。

2025年11月
26
27
28
29重阳节
30
31
1
2
3
4
5
6
7立冬
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22小雪
23
24
25
26
27
28
29
30
1
2
3
4
5
6
vue
<template>
  <ExCalendar v-model="selectedDate" :events="events" @event-click="handleEventClick" />
</template>

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

const selectedDate = ref(new Date());
const events = ref([
  {
    id: 1,
    title: '团队会议',
    date: new Date(2025, 9, 23),
    type: 'primary',
    description: '讨论Q1计划',
  },
  {
    id: 2,
    title: '项目截止',
    date: new Date(2025, 9, 22),
    type: 'danger',
    description: '提交最终版本',
  },
]);

const handleEventClick = (event, date) => {
  console.log('事件点击:', event, date);
};
</script>

签到功能

可以标记签到日期,显示签到状态。

2025年11月
26
27
28
29重阳节
30
31
1
2
3
4
5
6
7立冬
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22小雪
23
24
25
26
27
28
29
30
1
2
3
4
5
6
vue
<template>
  <ExCalendar v-model="selectedDate" :checked-in-dates="checkedInDates" />
</template>

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

const selectedDate = ref(new Date());
const checkedInDates = ref([new Date(2025, 9, 1), new Date(2025, 9, 2), new Date(2025, 9, 3)]);
</script>

显示农历

可以显示农历日期信息。

2025年11月
26初六
27初七
28初八
29重阳节
30初十
31十一
1十二
2十三
3十四
4十五
5十六
6十七
7立冬
8十九
9二十
10廿一
11廿二
12廿三
13廿四
14廿五
15廿六
16廿七
17廿八
18廿九
19三十
20十月
21初二
22小雪
23初四
24初五
25初六
26初七
27初八
28初九
29初十
30十一
1十二
2十三
3十四
4十五
5十六
6十七
vue
<template>
  <ExCalendar v-model="selectedDate" :show-lunar="true" />
</template>

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

const selectedDate = ref(new Date());
</script>

显示节气

可以显示二十四节气信息。

2025年11月
26初六
27初七
28初八
29重阳节
30初十
31十一
1十二
2十三
3十四
4十五
5十六
6十七
7立冬
8十九
9二十
10廿一
11廿二
12廿三
13廿四
14廿五
15廿六
16廿七
17廿八
18廿九
19三十
20十月
21初二
22小雪
23初四
24初五
25初六
26初七
27初八
28初九
29初十
30十一
1十二
2十三
3十四
4十五
5十六
6十七
vue
<template>
  <ExCalendar v-model="selectedDate" :show-lunar="true" :show-solar-term="true" />
</template>

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

const selectedDate = ref(new Date());
</script>

自定义节假日

可以自定义节假日显示。

2025年11月
26初六
27初七
28初八
29重阳节
30初十
31十一
1十二
2十三
3十四
4十五
5十六
6十七
7立冬
8十九
9二十
10廿一
11廿二
12廿三
13廿四
14廿五
15廿六
16廿七
17廿八
18廿九
19三十
20十月
21初二
22小雪
23初四
24初五
25初六
26初七
27初八
28初九
29初十
30十一
1十二
2十三
3十四
4十五
5十六
6十七
vue
<template>
  <ExCalendar v-model="selectedDate" :show-lunar="true" :holidays="holidays" />
</template>

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

const selectedDate = ref(new Date());
const holidays = ref([
  { name: '元旦', date: '01-01', type: 'holiday' },
  { name: '劳动节', date: '05-01', type: 'holiday' },
  { name: '国庆节', date: '10-01', type: 'holiday' },
  { name: '公司周年庆', date: '06-15', type: 'custom' },
]);
</script>

禁用日期

可以通过 disabledDate 函数禁用特定日期。

2025年11月
26
27
28
29重阳节
30
31
1
2
3
4
5
6
7立冬
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22小雪
23
24
25
26
27
28
29
30
1
2
3
4
5
6
vue
<template>
  <ExCalendar v-model="selectedDate" :disabled-date="disabledDate" />
</template>

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

const selectedDate = ref(new Date());

// 禁用周末
const disabledDate = (date) => {
  return date.getDay() === 0 || date.getDay() === 6;
};
</script>

全屏模式

日历可以全屏显示。

2025年11月
26
27
28
29重阳节
30
31
1
2
3
4
5
6
7立冬
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22小雪
23
24
25
26
27
28
29
30
1
2
3
4
5
6
vue
<template>
  <ExCalendar v-model="selectedDate" :fullscreen="true" :events="events" />
</template>

API

Props

属性说明类型默认值
modelValue当前选中日期Date-
mode视图模式'day' | 'week' | 'month' | 'year''month'
events事件列表CalendarEvent[][]
disabledDate禁用日期函数(date: Date) => boolean-
showToday是否显示今天按钮booleantrue
fullscreen是否全屏显示booleanfalse
checkedInDates签到日期列表(Date | string)[][]
showLunar是否显示农历booleanfalse
showSolarTerm是否显示节气booleantrue
holidays自定义节假日列表Holiday[][]
ariaLabel无障碍标签string-
class自定义CSS类名string | string[] | Record<string, boolean>-
style自定义样式string | Record<string, string | number>-

Events

事件名说明参数
update:modelValue值改变事件(value: Date)
select日期选择事件(date: Date, cell: CalendarDateCell)
month-change月份改变事件(year: number, month: number)
year-change年份改变事件(year: number)
mode-change视图模式改变事件(mode: CalendarMode)
date-click日期单元格点击事件(date: Date, cell: CalendarDateCell)
event-click事件点击事件(event: CalendarEvent, date: Date)

Methods

方法名说明参数
selectDate选择日期(date: Date)
goToday跳转到今天-
prevMonth上一个月-
nextMonth下一个月-
prevYear上一年-
nextYear下一年-
getElement获取DOM元素-

Types

CalendarEvent

typescript
interface CalendarEvent {
  /** 事件ID */
  id: string | number;
  /** 事件标题 */
  title: string;
  /** 事件日期 */
  date: Date | string;
  /** 事件类型 */
  type?: 'success' | 'warning' | 'danger' | 'info' | 'primary';
  /** 事件描述 */
  description?: string;
  /** 自定义数据 */
  data?: Record<string, unknown>;
}

CalendarDateCell

typescript
interface CalendarDateCell {
  /** 日期 */
  date: Date;
  /** 日期数字 */
  day: number;
  /** 是否当前月 */
  isCurrentMonth: boolean;
  /** 是否今天 */
  isToday: boolean;
  /** 是否选中 */
  isSelected: boolean;
  /** 是否禁用 */
  disabled: boolean;
  /** 该日期的事件列表 */
  events: CalendarEvent[];
  /** 签到状态 */
  checkedIn?: boolean;
  /** 农历日期 */
  lunar?: string;
  /** 节气 */
  solarTerm?: string;
  /** 节假日 */
  holiday?: string;
  /** 自定义数据 */
  data?: Record<string, unknown>;
}

Holiday

typescript
interface Holiday {
  /** 节假日名称 */
  name: string;
  /** 节假日日期(月-日格式,如 "01-01" 表示1月1日) */
  date: string;
  /** 节假日类型 */
  type?: 'festival' | 'holiday' | 'custom';
}

CalendarMode

typescript
type CalendarMode = 'day' | 'week' | 'month' | 'year';

无障碍支持

  • 支持键盘导航
  • 提供 ARIA 标签
  • 支持屏幕阅读器
  • 支持高对比度模式
  • 支持减少动画模式

主题定制

日历组件使用 CSS 变量进行主题定制:

css
.ex-calendar {
  --ex-calendar-bg: var(--ex-color-bg-secondary);
  --ex-calendar-border: var(--ex-color-border-primary);
  --ex-calendar-text: var(--ex-color-text-primary);
  --ex-calendar-today: var(--ex-color-neon-blue-500);
  --ex-calendar-selected: var(--ex-color-neon-pink-500);
}