# Календарь
Календарное представление. Поддерживаются три режима выбора: одна дата, диапазон и множественный выбор; range ограничивает границы выбираемых дат; режим panel отображается постоянно, режим input сворачивается в поле ввода и разворачивается по клику (панель монтируется в body).
Календарь
<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">Диапазон в режиме панели (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('ru-RU') : '(не выбрано)'
},
fmtArr(v) {
if (!Array.isArray(v) || v.length === 0) return '(не выбрано)'
return v.map((d) => d.toLocaleDateString('ru-RU')).join(' ~ ')
},
},
}
</script>
# Props
| Проп | Описание | Тип | По умолчанию |
|---|---|---|---|
| v-model | Текущий выбор: одна дата — Date, диапазон и множественный выбор — Date[] | Date \| Date[] | — |
| selection | Режим выбора | 'single' \| 'range' \| 'multiple' | 'single' |
| range | Диапазон выбираемых дат [start, end]; вне диапазона даты отключены | [Date, Date] | — |
| mode | Вид отображения: panel — постоянно открытая панель / input — свёрнуто в поле ввода | 'panel' \| 'input' | 'panel' |
| panels | Число одновременно отображаемых месячных панелей (располагаются в flex с переносом) | number | 1 |
| placeholder | Текст-плейсхолдер в режиме input | string | Языковой пакет |
| closeOnSelect | Автозакрытие после выбора в режиме input | boolean | true |
| sx | Сокращённая запись разметки через sx | — | — |
# Events
input (v-model), change (value), select (date)
# Slots
| Слот | Описание |
|---|---|
| header | Шапка месячной панели, слот-параметр { year, month } (по умолчанию «YYYY-MM») |
| cell | Ячейка даты, слот-параметр { date } (по умолчанию — номер дня) |
# Доступность
Панель имеет role="grid", строка дней недели — role="row", ячейки дат — role="gridcell"; отключённые даты получают aria-disabled, а триггер в режиме input поддерживает раскрытие с клавиатуры и перемещение стрелками.
Copyright © 2024-2026 FengMo WenXue