返回目录
组件详情入口
表单
@vean/ui
SCalendar

Calendar

Calendar 属于 表单 分类。建议先看演示与用法,再对照 API 表格完成接入和样式调整。

先用快捷跳转面板找到概述、用法、演示和 API,再往下细读完整文档内容。

快速跳转

同分类组件

如果你在同一类交互里做组合,这些组件通常会一起出现。

Calendar

概述

按月展示的日期网格组件,支持单选/多选、禁用与不可用日期、min/max 边界、自定义单元格渲染,以及 Compact 头部内置的月份/年份 Select 控件。适用于预订、排期或任何需要键盘可导航网格而非纯文本输入的日期选择场景。需要弹出触发器时搭配 SDatePicker;需要范围选择时使用范围型复合组件。

用法

特性

  • 📅 月网格 — 一个或多个月网格(numberOfMonths),语言环境感知的星期表头、今天与视图外标记
  • 🎚 受控 / 非受控 — 支持 v-model/defaultValue 单选日期或日期数组(multiple),底层由 useControllableState 驱动
  • ✅ 多选 — 点击或键盘切换日期;preventDeselect 保持选中粘性
  • ⌨️ 完整键盘支持 — ArrowLeft/ArrowRight/ArrowUp/ArrowDown 导航(RTL 反转、跨月翻页、跳过禁用日期);Enter/Space 选择
  • ⛓ 边界与匹配 — minValue/maxValue 限制翻页并禁用越界日期;isDateDisabled/isDateUnavailable 标记任意日期
  • 🧩 可组合插槽 — day、head-cell、heading、prev、next 插槽携带丰富 slot props;每个子部件支持 *Props 透传
  • 🔤 本地化 UI — locale、weekStartsOn、weekdayFormat;月份/年份 Select 控件携带本地化 aria-label
  • 🗓 月份/年份控件 — Compact 头部渲染 Select 控件快速跳转月份/年份,按 minValue/maxValue 禁用
  • ↕️ 固定周数 — fixedWeeks 渲染一致的 6 行网格;initialFocus 挂载时聚焦网格
  • 🚫 禁用 / 只读 — disabled 阻止全部交互;readonly 保留浏览但阻止选择

组件家族

  • SCalendar — 样式包装层,将 props 转发给 Aria compact 并注入 calendarVariants 类(12 个 slot,prev/next 复用按钮图标 recipe)
  • CalendarCompact(Aria)— CalendarRoot + 头部(prev/heading/next)+ 每月一个网格(grid head/body 行内的 CalendarCellTrigger)的数据驱动组合;无样式用法从 @vean/aria/calendar 导入
  • CalendarRoot(Aria)— 状态所有者:useControllableState 管理值与占位符,useCalendar 管理网格/月份翻页与校验,useCalendarState 派生选中/无效状态
  • CalendarCellTrigger / CalendarCell / CalendarGrid*(Aria)— 可编辑的日期按钮(键盘处理、焦点管理、数据属性)及其语义化网格单元格包装

演示

基础

Event Date, 2026年4月

禁用

Event Date, 2026年4月

自定义样式

Event Date, 2026年4月

API

Aria 层

14

Calendar<M>

40 属性2 事件6 插槽
属性
属性名类型默认值描述
class
ClassValue
—
应用于根元素的额外类名。
size
ThemeSize
—
组件的视觉尺寸。
ui
Partial<CalendarUi>
—
该组件的按槽类重写。
headerProps
CalendarHeaderProps
—
转发至 header 元素的属性。
headingProps
CalendarHeadingProps
—
传递给 heading 元素的属性。
prevProps
CalendarPrevProps
—
转发给前一个元素的属性。
nextProps
CalendarNextProps
—
属性将转发给下一个元素。
gridProps
CalendarGridProps
—
转发给网格元素的属性。
gridHeadProps
CalendarGridHeadProps
—
转发给网格头元素的属性。
gridBodyProps
CalendarGridBodyProps
—
转发至 grid 主体元素的属性。
gridRowProps
CalendarGridRowProps
—
转发给网格行元素的属性。
headCellProps
CalendarHeadCellProps
—
转发至 head 单元格元素的属性。
cellProps
CalendarCellProps
—
转发给 cell 元素的属性。
cellTriggerProps
CalendarCellTriggerProps
—
转发给单元格触发器的属性。
dir
Direction
—
组件的阅读方向。
locale
string
—
语言环境。
modelValue
CalendarModelValue<M>
—
当前模型值。
defaultValue
CalendarModelValue<M>
—
默认值。
multiple
M
—
是否支持多个值。
placeholder
DateValue
—
占位符。
defaultPlaceholder
DateValue
—
默认占位符。
disabled
boolean
—
该组件是否已禁用。
readonly
boolean
—
该组件是否为只读。
pagedNavigation
boolean
—
是否启用分页导航。
preventDeselect
boolean
—
是否禁止取消选择。
weekStartsOn
WeekStartsOn
—
本周从...开始。
weekdayFormat
WeekDayFormat
—
星期格式。
calendarLabel
string
—
日历标签。
fixedWeeks
boolean
—
是否为固定周数。
maxValue
DateValue
—
最大值。
minValue
DateValue
—
最小值。
numberOfMonths
number
—
月数。
initialFocus
boolean
—
是否为初始焦点。
isDateDisabled
DateMatcher
—
日期是否已禁用。
isDateUnavailable
DateMatcher
—
日期是否不可用。
nextPage
((placeholder: DateValue) => DateValue)
—
下一页。
prevPage
((placeholder: DateValue) => DateValue)
—
上一页。
disableDaysOutsideCurrentView
boolean
—
是否禁用当前视图范围外的日期。
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。
事件
事件名参数描述
update:modelValue
CalendarModelValue<M>
当模型值发生变化时触发。
update:placeholder
DateValue
当占位符值发生变化时触发。
插槽
插槽名参数描述
default
{ modelValue: CalendarModelValue<M>; }
默认插槽的自定义内容。
prev
{ disabled: boolean; }
prev 槽位的自定义内容。
heading
CalendarHeadingSlotProps
标题槽位的自定义内容。
next
{ disabled: boolean; }
下一个插槽的自定义内容。
head-cell
{ date: Date; index: number; label: string; }
用于“头单元格”插槽的自定义内容。
day
CalendarDaySlotProps
“day”时段的自定义内容。

CalendarCell

3 属性
属性
属性名类型默认值描述
date
Date
—
日期。
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。

CalendarCellTrigger

6 属性1 插槽
属性
属性名类型默认值描述
day
Date
—
Day。
month
Date
—
月份。
type
ButtonType
'button'
按钮元素的类型。可以是 'button'、'submit' 或 'reset' 之一。
disabled
boolean
—
该组件是否已禁用。
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。
插槽
插槽名参数描述
default
CalendarCellTriggerSlotProps
默认插槽的自定义内容。

CalendarCompact<M>

37 属性2 事件6 插槽
属性
属性名类型默认值描述
headerProps
CalendarHeaderProps
—
转发至 header 元素的属性。
headingProps
CalendarHeadingProps
—
传递给 heading 元素的属性。
prevProps
CalendarPrevProps
—
转发给前一个元素的属性。
nextProps
CalendarNextProps
—
属性将转发给下一个元素。
gridProps
CalendarGridProps
—
转发给网格元素的属性。
gridHeadProps
CalendarGridHeadProps
—
转发给网格头元素的属性。
gridBodyProps
CalendarGridBodyProps
—
转发至 grid 主体元素的属性。
gridRowProps
CalendarGridRowProps
—
转发给网格行元素的属性。
headCellProps
CalendarHeadCellProps
—
转发至 head 单元格元素的属性。
cellProps
CalendarCellProps
—
转发给 cell 元素的属性。
cellTriggerProps
CalendarCellTriggerProps
—
转发给单元格触发器的属性。
dir
Direction
—
组件的阅读方向。
locale
string
—
语言环境。
modelValue
CalendarModelValue<M>
—
当前模型值。
defaultValue
CalendarModelValue<M>
—
默认值。
multiple
M
—
是否支持多个值。
placeholder
DateValue
—
占位符。
defaultPlaceholder
DateValue
—
默认占位符。
disabled
boolean
—
该组件是否已禁用。
readonly
boolean
—
该组件是否为只读。
pagedNavigation
boolean
—
是否启用分页导航。
preventDeselect
boolean
—
是否禁止取消选择。
weekStartsOn
WeekStartsOn
—
本周从...开始。
weekdayFormat
WeekDayFormat
—
星期格式。
calendarLabel
string
—
日历标签。
fixedWeeks
boolean
—
是否为固定周数。
maxValue
DateValue
—
最大值。
minValue
DateValue
—
最小值。
numberOfMonths
number
—
月数。
initialFocus
boolean
—
是否为初始焦点。
isDateDisabled
DateMatcher
—
日期是否已禁用。
isDateUnavailable
DateMatcher
—
日期是否不可用。
nextPage
((placeholder: DateValue) => DateValue)
—
下一页。
prevPage
((placeholder: DateValue) => DateValue)
—
上一页。
disableDaysOutsideCurrentView
boolean
—
是否禁用当前视图范围外的日期。
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。
事件
事件名参数描述
update:modelValue
CalendarModelValue<M>
当模型值发生变化时触发。
update:placeholder
DateValue
当占位符值发生变化时触发。
插槽
插槽名参数描述
default
{ modelValue: CalendarModelValue<M>; }
默认插槽的自定义内容。
prev
{ disabled: boolean; }
prev 槽位的自定义内容。
heading
CalendarHeadingSlotProps
标题槽位的自定义内容。
next
{ disabled: boolean; }
下一个插槽的自定义内容。
head-cell
{ date: Date; index: number; label: string; }
用于“头单元格”插槽的自定义内容。
day
CalendarDaySlotProps
“day”时段的自定义内容。

CalendarGrid

2 属性
属性
属性名类型默认值描述
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。

CalendarGridBody

2 属性
属性
属性名类型默认值描述
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。

CalendarGridHead

2 属性
属性
属性名类型默认值描述
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。

CalendarGridRow

2 属性
属性
属性名类型默认值描述
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。

CalendarHeadCell

2 属性
属性
属性名类型默认值描述
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。

CalendarHeader

2 属性
属性
属性名类型默认值描述
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。

CalendarHeading

2 属性
属性
属性名类型默认值描述
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。

CalendarNext

5 属性
属性
属性名类型默认值描述
nextPage
((placeholder: DateValue) => DateValue)
—
下一页。
type
ButtonType
'button'
按钮元素的类型。可以是 'button'、'submit' 或 'reset' 之一。
disabled
boolean
—
该组件是否已禁用。
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。

CalendarPrev

5 属性
属性
属性名类型默认值描述
prevPage
((placeholder: DateValue) => DateValue)
—
上一页。
type
ButtonType
'button'
按钮元素的类型。可以是 'button'、'submit' 或 'reset' 之一。
disabled
boolean
—
该组件是否已禁用。
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。

CalendarRoot<M>

26 属性2 事件1 插槽
属性
属性名类型默认值描述
dir
Direction
—
组件的阅读方向。
locale
string
—
语言环境。
modelValue
CalendarModelValue<M>
—
当前模型值。
defaultValue
CalendarModelValue<M>
—
默认值。
multiple
M
—
是否支持多个值。
placeholder
DateValue
—
占位符。
defaultPlaceholder
DateValue
—
默认占位符。
disabled
boolean
—
该组件是否已禁用。
readonly
boolean
—
该组件是否为只读。
pagedNavigation
boolean
—
是否启用分页导航。
preventDeselect
boolean
—
是否禁止取消选择。
weekStartsOn
WeekStartsOn
—
本周从...开始。
weekdayFormat
WeekDayFormat
—
星期格式。
calendarLabel
string
—
日历标签。
fixedWeeks
boolean
—
是否为固定周数。
maxValue
DateValue
—
最大值。
minValue
DateValue
—
最小值。
numberOfMonths
number
—
月数。
initialFocus
boolean
—
是否为初始焦点。
isDateDisabled
DateMatcher
—
日期是否已禁用。
isDateUnavailable
DateMatcher
—
日期是否不可用。
nextPage
((placeholder: DateValue) => DateValue)
—
下一页。
prevPage
((placeholder: DateValue) => DateValue)
—
上一页。
disableDaysOutsideCurrentView
boolean
—
是否禁用当前视图范围外的日期。
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。
事件
事件名参数描述
update:modelValue
CalendarModelValue<M>
当模型值发生变化时触发。
update:placeholder
DateValue
当占位符值发生变化时触发。
插槽
插槽名参数描述
default
CalendarRootSlotProps<M>
默认插槽的自定义内容。

注意事项

架构与对标差异

CalendarRoot 通过 useControllableState 持有值(multiple 时为数组),以占位符驱动网格翻页,并把网格创建委托给 useCalendar(在 locale/周首日/占位符变化时重建网格,并以 minValue/maxValue 限制翻页)。useCalendarState 派生选中/无效状态。CalendarCellTrigger 是唯一交互部件:读取共享上下文,计算 data-focused/data-selected/data-today/data-unavailable/data-outside-view,处理 Arrow/Enter/Space 键(dir 感知方向,RTL 下 ArrowLeft/ArrowRight 互换),并在导航跨网格边界时翻到相邻月份。Compact 负责迭代月份/周/日与头部接线(prev/heading/next + 月份/年份 Select)。对标库多为单体日历面板;Aria/styled 分离、逐部件 *Props 透传与插槽驱动单元格渲染是差异点。

能力VeanUIAnt DesignElement PlusMantineNaive UIshadcn
Aria/styled 分离✅—————
单选 / 多选✅✅✅✅✅—
键盘网格导航✅✅✅✅✅✅
RTL 方向反转✅—————
numberOfMonths 网格✅——✅——
minValue/maxValue✅✅✅✅✅—
isDateDisabled/不可用✅✅✅✅✅—
fixedWeeks/weekStartsOn✅—✅✅——
月份/年份 Select 控件✅✅✅———
自定义 prevPage/nextPage✅—————
逐部件 *Props 透传✅—————
本地化 aria-label✅✅✅✅——

运行时注意事项

  • 值是本地零点的原生 Date(即 DateValue 模型:Date 或 { date, time? })。格式化/转换直接使用 date-fns 或 Intl。
  • multiple 会把模型形状变为 DateValue[];M 泛型由 prop 推断。
  • defaultValue/defaultPlaceholder 仅在挂载时读取——外部控制请使用 v-model。
  • isDateDisabled 与 isDateUnavailable 不同:禁用日期是策略性不可选,不可用日期还会被视觉标记(默认样式 line-through)。
  • 默认渲染当前月之外的日期;传入 disableDaysOutsideCurrentView 可禁用它。
  • prev/next 的 aria-label 默认为 locale 消息;可通过 prevProps/nextProps 逐按钮覆盖。
  • 导航按钮在 minValue/maxValue 处自动禁用;自定义 prevPage/nextPage 函数参与该计算。

常见问题

如何多选日期?

传入 multiple(模板中布尔简写可用)并把 v-model 绑定到 DateValue 数组。点击切换日期;preventDeselect 阻止移除。

如何禁止今天之前的日期?

传入 minValue={new Date(2026, 0, 1)}(任意 DateValue)。越界日期被禁用,prev 按钮在边界处自动禁用。

如何同时展示多个月?

设置 numberOfMonths={2}——日历并排渲染两个月网格,跨边界时一并翻页。

为什么未处理 PageUp/PageDown?

网格导航目前覆盖方向键、Enter/Space 与跨月翻页。PageUp/PageDown/Home/End(Ant Design/Element Plus 面板具备)为已排期的增强项。

如何用此组件构建日期范围?

范围专用网格使用 SRangeCalendar;或将两个 SCalendar 以 minValue/maxValue 互相绑定另一侧的选择。

更新日志

版本记录按发布版本分组,便于快速查看这个组件在不同版本里的实际变更。

v0.17.0

2026-05-03

对比版本

优化

删除未使用的道具并更新只读绑定

范围: calendar作者: soybeanjs查看提交aed69

v0.16.0

2026-05-01

对比版本

优化

添加可选择月份/年份的紧凑型页眉,并改进日历功能

范围: calendar作者: soybeanfe, Copilot查看提交2d4e6