Calendar 日历
为用户提供导航、查看日期或记录日程的功能。支持假期显示、日期范围选择、多选、周数显示等高级特性。
基础用法
设置 v-model 来指定当前选中的日期,默认为今天。日历采用现代化设计,具有精美的动画效果和交互体验。
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
|---|---|---|---|---|---|---|
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 | 31 | 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 |
假期显示
设置 show-holiday 开启中国法定节假日显示。假期会显示 "休" 标记,补班日显示 "班" 标记。
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
|---|---|---|---|---|---|---|
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 | 31 | 1 | 2 | 3 | 4 休 |
5 休 | 6 休 | 7 | 8 | 9 | 10 | 11 |
自定义内容
通过具名插槽 date-cell 来自定义日历单元格显示的内容。作用域参数 data 包含了丰富的日期信息。
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
|---|---|---|---|---|---|---|
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 | 31 | 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 |
日期范围限制
通过 min-date 和 max-date 限制可选择的日期范围。超出范围的日期将被禁用。
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
|---|---|---|---|---|---|---|
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 | 31 | 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 |
只读模式
设置 readonly 属性使日历进入只读模式,用户将无法选择日期。
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
|---|---|---|---|---|---|---|
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 | 31 | 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 |
范围选择
设置 selection-mode="range" 开启日期范围选择模式,配合 v-model:range-value 使用。
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
|---|---|---|---|---|---|---|
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 | 31 | 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 |
已选择:请选择日期范围
显示周数
设置 show-week-number 在日历左侧显示 ISO 周数。
| 周 | 日 | 一 | 二 | 三 | 四 | 五 | 六 |
|---|---|---|---|---|---|---|---|
| 9 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 10 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 11 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 12 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
| 13 | 29 | 30 | 31 | 1 | 2 | 3 | 4 |
| 14 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
禁用指定日期
通过 disabled-date 函数自定义禁用逻辑。以下示例禁用了所有周末。
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
|---|---|---|---|---|---|---|
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 | 31 | 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 |
全屏模式
设置 fullscreen 使日历占满父容器高度,适合用于日程管理页面。
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
|---|---|---|---|---|---|---|
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 | 31 | 1 | 2 | 3 | 4 休 |
5 休 | 6 休 | 7 | 8 | 9 | 10 | 11 |
尺寸
提供 small、default、large 三种尺寸。
Small 尺寸
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
|---|---|---|---|---|---|---|
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 | 31 | 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 |
Default 尺寸(默认)
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
|---|---|---|---|---|---|---|
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 | 31 | 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 |
Large 尺寸
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
|---|---|---|---|---|---|---|
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 | 31 | 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 |
在 Nuxt 中使用
Calendar 组件完全支持 Nuxt 3/4 的 SSR 渲染。在 Nuxt 项目中使用时,组件会自动导入,无需手动注册。
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
|---|---|---|---|---|---|---|
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 | 31 | 1 | 2 | 3 | 4 休 |
5 休 | 6 休 | 7 | 8 | 9 | 10 | 11 |
SSR 注意事项:
- ✅ 基础渲染和矩阵计算完全支持 SSR
- ✅ 假期数据在服务端完成计算
- ✅ 插槽内容在服务端生成,Hydration 表现优异
- ⚠️ 范围选择的 hover 效果为客户端行为
SSR 性能
Calendar 内部采用静态日期缓存逻辑,即使在 SSR 环境下频繁刷新,内存占用也极低。
API
Props
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| v-model | 绑定值(单选模式) | Date | — |
| default-value | 默认选中的日期 | Date | — |
| mode | 视图模式 | 'month' | 'year' | 'month' |
| first-day-of-week | 每周的第一天(1-7,1为周一) | number | 7 (周日) |
| min-date | 可选择的最小日期 | Date | — |
| max-date | 可选择的最大日期 | Date | — |
| readonly | 是否只读 | boolean | false |
| disabled | 是否禁用 | boolean | false |
| disabled-date | 自定义禁用日期函数 | (date: Date) => boolean | — |
| show-holiday | 是否显示节假日标记 | boolean | false |
| holidays | 自定义假期数据 | HolidayMap | {} |
| show-week-number | 是否显示周数 | boolean | false |
| fullscreen | 是否全屏模式(占满容器) | boolean | false |
| selection-mode | 选择模式 | 'single' | 'range' | 'multiple' | 'single' |
| range-value | 范围选择值 | [Date?, Date?] | — |
| multiple-value | 多选值 | Date[] | [] |
| show-other-months | 是否显示非当月日期 | boolean | true |
| highlight-weekends | 是否高亮周末 | boolean | true |
| size | 日历尺寸 | 'small' | 'default' | 'large' | 'default' |
| cell-class-name | 单元格自定义类名函数 | (date: Date) => string | string[] | object | — |
| month-header-format | 标题格式化 | string | 'YYYY 年 MM 月' |
Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| change | 选中日期发生变化时触发 | (date: Date) => void |
| select | 点击日期单元格时触发 | (date: Date, cell: CalendarDateCell) => void |
| panel-change | 面板显示的年月或模式发生变化时触发 | `(date: Date, mode: 'month' |
| range-change | 范围选择完成时触发 | (range: [Date, Date]) => void |
Slots
| 插槽名 | 说明 | 参数 |
|---|---|---|
| header | 自定义日历头部 | { date: string } |
| date-cell | 自定义日期单元格内容 | { data: CalendarDateCell } |
| footer | 自定义日历底部 | — |
Expose
通过 ref 可以访问到组件内部暴露的方法和属性:
| 方法/属性名 | 说明 | 类型 |
|---|---|---|
| displayDate | 当前显示的视口日期对象 (Dayjs) | Ref<Dayjs> |
| selectedDate | 当前选中的日期(单选模式, Dayjs) | `Ref<Dayjs |
| moveMonth | 切换月份 (参数 delta 为 1 或 -1) | (delta: number) => void |
| goToday | 组件跳转至今天 | () => void |
| selectDate | 手动选中某个日期单元格 | (cell: CalendarDateCell) => void |
CalendarDateCell 类型
| 属性 | 说明 | 类型 |
|---|---|---|
| day | 格式化的日期字符串(YYYY-MM-DD) | string |
| date | 原始 Date 对象 | Date |
| type | 日期类型 | 'prev-month' | 'current-month' | 'next-month' |
| isSelected | 是否选中 | boolean |
| isToday | 是否今天 | boolean |
| isDisabled | 是否禁用 | boolean |
| isWeekend | 是否周末 | boolean |
| isHoliday | 是否假期 | boolean |
| holidayName | 假期名称 | string | undefined |
| isWorkday | 是否补班日 | boolean |
| isInRange | 是否在范围内 | boolean |
| isRangeStart | 是否范围起始 | boolean |
| isRangeEnd | 是否范围结束 | boolean |
HolidayMap 类型
type HolidayMap = Record<string, {
name: string // 假期名称
isOffDay: boolean // true=放假, false=补班
}>主题变量
Calendar 组件支持通过覆盖以下 CSS 变量来自定义局部样式。所有颜色变量已与全局主题系统对接,自动支持暗黑模式:
| 变量名 | 说明 | 默认值 |
|---|---|---|
--yh-calendar-bg | 日历基础背景 | var(--yh-bg-color) |
--yh-calendar-text | 默认文字颜色 | var(--yh-text-color-primary) |
--yh-calendar-primary | 选中/今天主题色 | var(--yh-color-primary) |
--yh-calendar-primary-light | 范围/悬浮背景色 | var(--yh-color-primary-light-9) |
--yh-calendar-primary-dark | 选中悬浮加深色 | var(--yh-color-primary-dark-2) |
--yh-calendar-cell-height | 单元格高度 | 100px |
--yh-calendar-cell-radius | 单元格圆角 | var(--yh-radius-lg) |
--yh-calendar-head-height | 头部高度 | 80px |
--yh-calendar-title-size | 顶部标题字号 | 22px |
--yh-calendar-weekday-color | 星期表头颜色 | var(--yh-text-color-secondary) |
--yh-calendar-holiday-color | 假期标记颜色 | var(--yh-color-danger) |
--yh-calendar-week-number-color | 周数文字颜色 | var(--yh-text-color-placeholder) |
样式兼容性说明
由于 Calendar 内部采用标准 table 布局,如果您在 VitePress、Markdown 或某些具有激进全局 Table 样式的后台系统中使用,可能因为全局样式的斑马纹(Zebra Line)或边框注入导致背景显示异常。
核心样式隔离
YH-UI 遵循源码纯净原则,组件 SCSS 中不包含任何针对特定文档环境的暴力 !important 补丁。如果您在自己的 Markdown 环境中发现背景消失或出现多余边距,可以尝试在项目中添加以下全局样式代码:
/* 清理文档环境对日历表格的干扰 */
.your-container-class .yh-calendar__table,
.your-container-class .yh-calendar__table tr,
.your-container-class .yh-calendar__table td {
background-color: transparent !important;
border: none !important;
margin: 0 !important;
padding: 0 !important;
}为什么使用 !important?
这是为了压制某些 Markdown 渲染器注入的高权重全局选择器(如 .markdown-body table tr:nth-child(2n))。在普通的 Vue/Nuxt 业务项目中,您无需添加这些补丁。
高级用法示例
结合日程管理
展示如何在日历单元格中自定义内容,模拟真实的日程安排。
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
|---|---|---|---|---|---|---|
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 | 31 | 1 | 2 | 3 | 4 休 |
5 休 | 6 休 | 7 | 8 | 9 | 10 | 11 |
会议室预约系统
演示利用 selection-mode="range" 实现会议室预定逻辑,并限制不可选日期。
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
|---|---|---|---|---|---|---|
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 | 31 | 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 |