# Calendar

A calendar view. Three selection modes — single / a span of time / multiple — with range constraining the selectable date bounds; panel mode is always visible, while input mode collapses into a text field that expands on click (the panel is appended to the body).

Calendar
<template>
  <div class="demo-col" style="max-width: none">
    <div class="demo-row" style="align-items: flex-start; flex-wrap: nowrap">
      <LhCalendar v-model="single" selection="single" />
      <LhCalendar v-model="span" selection="range" mode="input" placeholder="选择一段时间" />
    </div>
    <p class="demo-note">单选:{{ fmt(single) }}|时间段:{{ fmtArr(span) }}</p>
    <div class="demo-row" style="align-items: flex-start; flex-wrap: nowrap; margin-top: 16px">
      <LhCalendar v-model="multi" selection="multiple" :panels="2" :close-on-select="false" />
      <LhCalendar v-model="strict" selection="range" mode="panel" />
    </div>
    <p class="demo-note">多选(panels=2 双联面板,closeOnSelect=false 不自动收起):{{ fmtArr(multi) }}</p>
    <p class="demo-note">面板模式 range(mode="panel"):{{ fmtArr(strict) }}</p>
    <div class="demo-row" style="align-items: flex-start; flex-wrap: nowrap; margin-top: 16px">
      <LhCalendar v-model="clamped" selection="single" :range="bounds" />
    </div>
    <p class="demo-note">range 限制可选区间(仅 2026-10-01 ~ 2026-10-15 可选):{{ fmt(clamped) }}</p>
  </div>
</template>

<script>
export default {
  data: () => ({
    single: new Date(2026, 9, 3),
    span: [],
    multi: [],
    strict: [],
    clamped: new Date(2026, 9, 5),
    bounds: [new Date(2026, 9, 1), new Date(2026, 9, 15)],
  }),
  methods: {
    fmt(v) {
      return v instanceof Date ? v.toLocaleDateString('zh-CN') : '(未选择)'
    },
    fmtArr(v) {
      if (!Array.isArray(v) || v.length === 0) return '(未选择)'
      return v.map((d) => d.toLocaleDateString('zh-CN')).join(' ~ ')
    },
  },
}
</script>

# Props

Prop Description Type Default
v-model Current selection; a Date for single, a Date[] for a span or multiple Date \| Date[] —
selection Selection mode 'single' \| 'range' \| 'multiple' 'single'
range Selectable date range [start, end]; dates outside are disabled [Date, Date] —
mode Display form: panel for an always-visible panel / input for a collapsed text field 'panel' \| 'input' 'panel'
panels Number of month panels shown at once (laid out with flex wrap) number 1
placeholder Placeholder text for input mode string locale message
closeOnSelect Whether input mode collapses after a selection boolean true
sx sx shorthand layout props — —

# Events

Event Description Callback args
input v-model event —
change Emitted when the selection changes (value)
select Emitted when a date cell is selected (date)

# Slots

Slot Description
header Month panel header; scope param { year, month } (renders "YYYY 年 M 月" by default)
cell Date cell; scope param { date } (renders the day number by default)

# Accessibility

The panel is role="grid", the weekday row is role="row", and the date cells are role="gridcell"; disabled dates set aria-disabled, and the input-mode trigger supports keyboard expansion and arrow-key navigation.

Last Updated: 10/12/2026, 11:57:05 PM

Copyright © 2024-2026 FengMo WenXue