Skip to content

Calendar 日历

日期面板。支持单选、多选、区间三种模式,以及日期标记。

三种模式

单选:Tue Sep 15 2026

多选:(未选)

区间:(未选)

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

const single = ref(new Date())
const multiple = ref([])
const range = ref(null)
</script>

<template>
  <SrCalendar v-model="single" mode="single" />
  <SrCalendar v-model="multiple" mode="multiple" />
  <SrCalendar v-model="range" mode="range" />
</template>

值类型随模式变化

这是使用 SrCalendar 最容易出错的地方:

模式v-model 类型说明
singleDate | null单个日期
multipleDate[]日期数组
range[Date, Date] | null起止元组

SrDatePicker 的值类型不同

SrDatePickerv-model'YYYY-MM-DD' 字符串, 而 SrCalendarDate 对象

为什么不一样:日历面板通常嵌在页面里直接与其他 Date 计算交互 (比如算某天有没有安排),用对象更顺手;而日期选择器的值要提交到接口、 存进表单,字符串更通用。

两者都能用 parseDate() / formatDate() 互相转换。

日期标记

cellMeta 是一个函数,每次渲染每个日期时调用一次,返回该格子的附加信息。

带角标的日期表示「当天有多少安排」或「空闲」,由宿主数据决定

vue
<script setup>
// 返回 undefined 表示该日期无标记
const cellMeta = (date) => {
  const day = date.getDate()

  if (day % 7 === 0) return { badge: '3' }        // 右上角角标
  if (day % 5 === 0) return { badge: '空闲' }      // 短文本
  return undefined
}
</script>

<template>
  <SrCalendar v-model="picked" :cell-meta="cellMeta" />
</template>

返回对象支持三个字段:

字段类型说明
disabledboolean该日期是否不可选
badgestring右上角角标(数字或短文本)
labelstring替换日期数字的显示文本

cellMeta 而不是传一个「有数据的日期数组」

传数组需要组件每次渲染时都去数组里查找,复杂度是 O(n) 每格—— 一个月 42 格就是 42 次查找。

用函数则把「查询」交给宿主:宿主可以用 Map 做到 O(1), 或者直接从已有的数据结构里取。组件只负责调用与渲染。

周起始日

week-start 设为 1 时以周一开始——中国大陆的习惯。

vue
<SrCalendar :week-start="1" />   <!-- 周一 -->
<SrCalendar :week-start="0" />   <!-- 周日(默认) -->

年月选择器

show-month-picker 显示顶部的年 / 月下拉,方便快速跳到较远的月份。

vue
<SrCalendar :show-month-picker="true" />

指定初始月份

month 控制面板初始显示的月份,不影响选中值

vue
<SrCalendar v-model="picked" :month="new Date(2026, 0, 1)" />

用于「先跳到某个历史月份」这类场景——比如从「上次记录的日期」开始浏览。

禁用

vue
<SrCalendar disabled />

Props

名称类型默认值说明
modelValueDate | Date[] | [Date, Date] | nullnull当前值,类型随 mode 变化
mode'single' | 'multiple' | 'range''single'选择模式
monthDate当前月初始显示的月份
weekStart0 | 10周起始日
showTodaybooleantrue是否显示「今天」按钮
showMonthPickerbooleanfalse是否显示年月下拉
cellMeta(date) => { disabled?, badge?, label? }每个日期的附加信息
disabledbooleanfalse是否整体禁用

事件

事件参数说明
update:modelValuemodelValue选中值变化
changemodelValue同上(语义化事件)
panelChangeDate面板切换月份时触发

无障碍

  • <table> 语义表达日历网格——日期天然是「行 × 列」的结构, 读屏软件能播报「第 3 行第 2 列」帮助定位
  • 今天带 aria-current="date",选中日期带 aria-selected
  • 每个日期格子的 aria-label 是完整日期(如「2026 年 9 月 14 日,星期一」), 而不是只有数字 14——脱离上下文,「14」对读屏用户毫无意义
  • 方向键在格子间移动,Enter / Space 选中

自用组件库 · 源码分发 · 不发布 npm