Calendar カレンダー - Vant 4
日付選択、範囲選択、複数日選択などの機能を提供します
導入
import { Calendar } from 'vant';
app.use(Calendar);コード例
切り替えモード
switch-mode 属性で、カレンダーの表示モードを設定できます。これにより、年月を素早く切り替えることができます。
<van-calendar
v-model:show="show"
title="切り替えモード"
switch-mode="year-month"
/>
<van-button type="primary" @click="show = true">表示</van-button>単一の日付を選択
type を single に設定すると、単一の日付を選択できます。これは重要な日付をマークするのに最適です。
<van-calendar v-model:show="show" @confirm="onConfirm" />
<van-cell title="日付" :value="date || '選択してください'" @click="show = true" is-link />import { ref } from 'vue';
export default {
setup() {
const date = ref('');
const show = ref(false);
const formatDate = (date) => {
return `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`;
};
const onConfirm = (value) => {
show.value = false;
date.value = formatDate(value);
};
return { date, show, onConfirm };
},
};複数の日付を選択
type を multiple に設定すると、複数の日付を一度に選択できます。フィットネス計画や休日のマークなどに便利です。
<van-calendar
v-model:show="show"
type="multiple"
@confirm="onConfirm"
/>
<van-cell title="複数日付" :value="text || '選択してください'" @click="show = true" is-link />import { ref } from 'vue';
export default {
setup() {
const text = ref('');
const show = ref(false);
const onConfirm = (dates) => {
show.value = false;
text.value = `${dates.length} 日を選択しました`;
};
return { text, show, onConfirm };
},
};日付範囲を選択
type を range に設定すると、開始日と終了日からなる日付範囲を選択できます。休暇計画やプロジェクト期間の設定などに最適です。
<van-calendar
v-model:show="show"
type="range"
@confirm="onConfirm"
/>
<van-cell title="日付範囲" :value="date || '選択してください'" @click="show = true" is-link />import { ref } from 'vue';
export default {
setup() {
const date = ref('');
const show = ref(false);
const formatDate = (date) => `${date.getMonth() + 1}/${date.getDate()}`;
const onConfirm = (values) => {
const [start, end] = values;
show.value = false;
date.value = `${formatDate(start)} - ${formatDate(end)}`;
};
return { date, show, onConfirm };
},
};Tips: デフォルトでは、日付範囲の開始と終了は同日にできませんが、
allow-same-day属性を設定することで同日を選択できるようになります。
即時選択
show-confirm を false に設定すると、確認ボタンが非表示になり、日付を選択するとすぐに confirm イベントがトリガーされます。よりスムーズな体験が実現できます。
<van-calendar
v-model:show="show"
:show-confirm="false"
@confirm="onConfirm"
/>
<van-cell title="即時選択" :value="date || '選択してください'" @click="show = true" is-link />カスタムカラー
color 属性を使用して、カレンダーのテーマカラーをカスタマイズできます。ブランドカラーに合わせて変更することができます。
<van-calendar v-model:show="show" color="#07c160" />
<van-button type="success" @click="show = true">緑色カレンダー</van-button>カスタム日付範囲
min-date と max-date 属性を使用して、ユーザーが選択できる日付範囲を制限できます。予約システムやイベント登録などの時間制限がある場面に最適です。
<van-calendar
v-model:show="show"
:min-date="minDate"
:max-date="maxDate"
/>
<van-button type="primary" @click="show = true">範囲を制限</van-button>import { ref } from 'vue';
export default {
setup() {
const show = ref(false);
return {
show,
minDate: new Date(2010, 0, 1),
maxDate: new Date(2010, 0, 31),
};
},
};カスタムボタンテキスト
confirm-text 属性で確認ボタンのテキストをカスタマイズできます。より個性的なボタン文案にすることができます。
<van-calendar
v-model:show="show"
confirm-text="決定"
confirm-disabled-text="選択してください"
/>
<van-button type="primary" @click="show = true">カスタムボタン</van-button>カスタム日付文案
formatter 関数を使用して、各日付の表示内容をカスタマイズできます。特別な日付に独自の表示を追加することができます。
<van-calendar
v-model:show="show"
type="range"
:formatter="formatter"
/>
<van-button type="primary" @click="show = true">カスタムフォーマット</van-button>export default {
setup() {
const formatter = (day) => {
const month = day.date.getMonth() + 1;
const date = day.date.getDate();
if (month === 5) {
if (date === 1) {
day.topInfo = '労働者の日';
} else if (date === 4) {
day.topInfo = '青年の日';
} else if (date === 11) {
day.text = '今日';
}
}
if (day.type === 'start') {
day.bottomInfo = 'チェックイン';
} else if (day.type === 'end') {
day.bottomInfo = 'チェックアウト';
}
return day;
};
return { formatter };
},
};カスタムポップアップ位置
position 属性でポップアップの表示位置をカスタマイズできます。top、left、right から選択できます。
<van-calendar v-model:show="show" position="right" />
<van-button type="primary" @click="show = true">右側に表示</van-button>日付範囲の最大範囲
max-range 属性を使用して、日付範囲の最大選択日数を指定できます。選択範囲が制限を超えると、指定したメッセージが表示されます。
<van-calendar
v-model:show="show"
type="range"
:max-range="3"
range-prompt="最大3日間まで選択できます"
/>
<van-button type="primary" @click="show = true">範囲制限</van-button>週の開始日をカスタマイズ
first-day-of-week 属性で週の開始日を設定できます。
<van-calendar v-model:show="show" :first-day-of-week="1" />
<van-button type="primary" @click="show = true">月曜日を開始に</van-button>フラット表示
poppable を false に設定すると、カレンダーはポップアップ形式ではなく、ページ内に直接表示されます。
<van-calendar
title="フラット表示"
:poppable="false"
:show-confirm="false"
/>API
Props
| パラメータ | 説明 | 型 | デフォルト値 |
|---|---|---|---|
| type | 選択タイプ:single 単一の日付選択、multiple 複数の日付選択、range 日付範囲選択 | string | single |
switch-mode v4.9.0 | 切り替えモード:none すべての月をフラット表示、month 月単位で切り替え、year-month 年と月単位で切り替え | string | none |
| title | カレンダーのタイトル | string | 日付選択 |
| color | テーマカラー、下部ボタンと選択された日付に適用 | string | #1989fa |
| min-date | 選択可能な最小日付 | Date | switch-mode が none の場合は現在の日付 |
| max-date | 選択可能な最大日付 | Date | switch-mode が none の場合は現在の日付の6か月後 |
| default-date | デフォルトで選択される日付、type が multiple または range の場合は配列、null を渡すとデフォルトで選択なし | Date | Date[] | null | 今日 |
| row-height | 日付の行の高さ | number | string | 64 |
| formatter | 日付フォーマット関数 | (day: Day) => Day | - |
| poppable | カレンダーをポップアップ形式で表示するかどうか | boolean | true |
| lazy-render | 表示領域のコンテンツのみをレンダリングするかどうか | boolean | true |
| show-mark | 月の背景ウォーターマークを表示するかどうか | boolean | true |
| show-title | カレンダーのタイトルを表示するかどうか | boolean | true |
| show-subtitle | カレンダーのサブタイトル(年月)を表示するかどうか | boolean | true |
| show-confirm | 確認ボタンを表示するかどうか | boolean | true |
| readonly | 読み取り専用モードかどうか、読み取り専用モードでは日付を選択できない | boolean | false |
| confirm-text | 確認ボタンのテキスト | string | 確認 |
| confirm-disabled-text | 確認ボタンが無効な状態のテキスト | string | 確認 |
| first-day-of-week | 週の開始日を設定 | 0-6 | 0 |
Calendar Poppable Props
Calendar の poppable が true の場合、以下の props が使用可能です:
| パラメータ | 説明 | 型 | デフォルト値 |
|---|---|---|---|
| v-model:show | カレンダーポップアップを表示するかどうか | boolean | false |
| position | ポップアップの位置、top、right、left から選択 | string | bottom |
| round | 角丸のポップアップを表示するかどうか | boolean | true |
| close-on-popstate | ページを戻るときに自動的に閉じるかどうか | boolean | true |
| close-on-click-overlay | マスクをクリックして閉じるかどうか | boolean | true |
| safe-area-inset-top | 上部安全領域の適応を有効にするかどうか | boolean | false |
| safe-area-inset-bottom | 下部安全領域の適応を有効にするかどうか | boolean | true |
| teleport | マウント先のノードを指定、Teleport コンポーネントの to 属性と同じ | string | Element | - |
Calendar Range Props
Calendar の type が range の場合、以下の props が使用可能です:
| パラメータ | 説明 | 型 | デフォルト値 |
|---|---|---|---|
| max-range | 日付範囲の最大選択日数 | number | string | 制限なし |
| range-prompt | 範囲選択が最大選択日数を超えた場合のメッセージ | string | 最多选择 xx 天 |
| show-range-prompt | 範囲選択が最大選択日数を超えた場合にメッセージを表示するかどうか | boolean | true |
| allow-same-day | 日付範囲の開始と終了を同日に許可するかどうか | boolean | false |
Calendar Multiple Props
Calendar の type が multiple の場合、以下の props が使用可能です:
| パラメータ | 説明 | 型 | デフォルト値 |
|---|---|---|---|
| max-range | 日付の最大選択数 | number | string | 制限なし |
| range-prompt | 選択が最大数を超えた場合のメッセージ | string | 最多选择 xx 天 |
Day データ構造
カレンダーの各日付は Day オブジェクトに対応します。formatter 属性で Day オブジェクトの内容をカスタマイズできます。
| キー名 | 説明 | 型 |
|---|---|---|
| date | 日付に対応する Date オブジェクト | Date |
| type | 日付のタイプ、selected、start、middle、end、disabled、start-end、multiple-selected、multiple-middle、placeholder から選択 | string |
| text | 中央に表示されるテキスト | string |
| topInfo | 上部のヒント情報 | string |
| bottomInfo | 下部のヒント情報 | string |
| className | 追加のクラス名 | string |
Events
| イベント名 | 説明 | コールバックパラメータ |
|---|---|---|
| select | 任意の日付をクリックして選択したときにトリガーされます | value: Date | Date[] |
| confirm | 日付の選択が完了したときにトリガーされます。show-confirm が true の場合は、確認ボタンをクリックするとトリガーされます | value: Date | Date[] |
| open | ポップアップを開くときにトリガーされます | - |
| close | ポップアップを閉じるときにトリガーされます | - |
| opened | ポップアップを開いてアニメーションが終了したときにトリガーされます | - |
| closed | ポップアップを閉じてアニメーションが終了したときにトリガーされます | - |
| unselect | Calendar コンポーネントの type が multiple の場合、日付の選択を解除したときにトリガーされます | value: Date |
| month-show | ある月が表示領域に入ったときにトリガーされます(switch-mode が none の場合に有効) | { date: Date, title: string } |
| over-range | 範囲選択が最大選択日数を超えたときにトリガーされます | - |
| click-subtitle | カレンダーのサブタイトルをクリックしたときにトリガーされます | event: MouseEvent |
click-disabled-date v4.7.0 | 無効な日付をクリックしたときにトリガーされます | value: Date | Date[] |
click-overlay v4.9.16 | マスクをクリックしたときにトリガーされます | event: MouseEvent |
| panel-change | カレンダーパネルが切り替わったときにトリガーされます(switch-mode が none 以外の場合に有効) | { date: Date } |
Slots
| 名前 | 説明 | パラメータ |
|---|---|---|
| title | カスタムタイトル | - |
| subtitle | カスタムカレンダーサブタイトル | { text: string, date?: Date } |
month-title v4.0.9 | 各月のサブタイトルをカスタマイズ | { text: string, date: Date } |
| footer | 下部領域の内容をカスタマイズ | - |
| confirm-text | 確認ボタンの内容をカスタマイズ | { disabled: boolean } |
| top-info | 日付の上部のヒント情報をカスタマイズ | day: Day |
| bottom-info | 日付の下部のヒント情報をカスタマイズ | day: Day |
| text | 日付の内容をカスタマイズ | day: Day |
| prev-month | 前の月のボタンをカスタマイズ | { disabled: boolean } |
| prev-year | 前の年のボタンをカスタマイズ | { disabled: boolean } |
| next-month | 次の月のボタンをカスタマイズ | { disabled: boolean } |
| next-year | 次の年のボタンをカスタマイズ | { disabled: boolean } |
メソッド
ref を使用して Calendar インスタンスを取得し、インスタンスメソッドを呼び出すことができます。詳細については、コンポーネントインスタンスメソッドを参照してください。
| メソッド名 | 説明 | パラメータ | 戻り値 |
|---|---|---|---|
| reset | 選択した日付を指定された日付にリセットします。パラメータがない場合はデフォルトの日付にリセットします | date?: Date | Date[] | - |
| scrollToDate | 特定の日付までスクロールします | date: Date | - |
| getSelectedDate | 選択された日付を取得します | - | Date | Date[] | null |
タイプ定義
コンポーネントは次のTypeScriptタイプをエクスポートしています:
export type CalendarSwitchMode = 'none' | 'month' | 'year-month';
export type CalendarType = 'single' | 'multiple' | 'range';
export type CalendarProps = {
type?: CalendarType;
switchMode?: CalendarSwitchMode;
title?: string;
color?: string;
minDate?: Date;
maxDate?: Date;
defaultDate?: Date | Date[] | null;
rowHeight?: number | string;
formatter?: (day: CalendarDayItem) => CalendarDayItem;
poppable?: boolean;
lazyRender?: boolean;
showMark?: boolean;
showTitle?: boolean;
showSubtitle?: boolean;
showConfirm?: boolean;
readonly?: boolean;
confirmText?: string;
confirmDisabledText?: string;
firstDayOfWeek?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
// Poppable props
show?: boolean;
position?: 'top' | 'bottom' | 'left' | 'right';
round?: boolean;
closeOnPopstate?: boolean;
closeOnClickOverlay?: boolean;
safeAreaInsetTop?: boolean;
safeAreaInsetBottom?: boolean;
teleport?: string | Element;
// Range props
maxRange?: number | string;
rangePrompt?: string;
showRangePrompt?: boolean;
allowSameDay?: boolean;
};
export type CalendarDayItem = {
date: Date;
type: CalendarDayType;
text: string;
topInfo?: string;
bottomInfo?: string;
className?: string;
};
export type CalendarDayType =
| 'selected'
| 'start'
| 'middle'
| 'end'
| 'disabled'
| 'start-end'
| 'multiple-selected'
| 'multiple-middle'
| 'placeholder';
export type CalendarInstance = {
reset: (date?: Date | Date[]) => void;
scrollToDate: (date: Date) => void;
getSelectedDate: () => Date | Date[] | null;
};テーマカスタマイズ
CSS変数
以下のCSS変数を使用して、コンポーネントのスタイルをカスタマイズできます。カスタマイズ方法については、テーマカスタマイズガイドを参照してください。
| 変数名 | デフォルト値 | 説明 |
|---|---|---|
| --van-calendar-background | var(--van-background-2) | - |
| --van-calendar-popup-height | 80% | - |
| --van-calendar-header-shadow | 0 2px 10px rgba(125, 126, 128, 0.16) | - |
| --van-calendar-header-title-height | 44px | - |
| --van-calendar-header-title-font-size | var(--van-font-size-lg) | - |
| --van-calendar-header-subtitle-font-size | var(--van-font-size-md) | - |
| --van-calendar-header-action-width | 28px | - |
| --van-calendar-header-action-color | var(--van-text-color) | - |
| --van-calendar-header-action-disabled-color | var(--van-text-color-3) | - |
| --van-calendar-weekdays-height | 30px | - |
| --van-calendar-weekdays-font-size | var(--van-font-size-sm) | - |
| --van-calendar-month-title-font-size | var(--van-font-size-md) | - |
| --van-calendar-month-mark-color | fade(var(--van-gray-2), 80%) | - |
| --van-calendar-month-mark-font-size | 160px | - |
| --van-calendar-day-height | 64px | - |
| --van-calendar-day-font-size | var(--van-font-size-lg) | - |
| --van-calendar-day-margin-bottom | 4px | - |
| --van-calendar-day-disabled-color | var(--van-text-color-3) | - |
| --van-calendar-range-edge-color | var(--van-white) | - |
| --van-calendar-range-edge-background | var(--van-primary-color) | - |
| --van-calendar-range-middle-color | var(--van-primary-color) | - |
| --van-calendar-range-middle-background-opacity | 0.1 | - |
| --van-calendar-selected-day-size | 54px | - |
| --van-calendar-selected-day-color | var(--van-white) | - |
| --van-calendar-selected-day-background | var(--van-primary-color) | - |
| --van-calendar-info-font-size | var(--van-font-size-xs) | - |
| --van-calendar-info-line-height | var(--van-line-height-xs) | - |
| --van-calendar-confirm-button-height | 36px | - |
| --van-calendar-confirm-button-margin | 7px 0 | - |
よくある質問
formatter で非同期で返されるデータを使用するには?
formatter で非同期で返されるデータを使用する必要がある場合は、計算プロパティを使用して動的に formatter 関数を作成できます。以下に例を示します:
const asyncData = ref();
const formatter = computed(() => {
if (!asyncData.value) {
return (day) => day;
}
return (day) => {
day.bottomInfo = asyncData.value;
return day;
};
});
setTimeout(() => {
asyncData.value = 'バックエンドからのテキスト';
}, 3000);iOS でコンポーネントの初期化に失敗する?
iOS でコンポーネントがレンダリングされない問題に直面した場合、new Date('2020-01-01') のような中線で区切られた日付形式を使用していないか確認してください。iOS はこの形式をサポートしていません。正しい方法は new Date('2020/01/01') です。
この問題の詳細な説明:stackoverflow。
あるいは、new Date(2020, 0, 1) のような、すべてのシステムとブラウザで互換性がある方法を採用するべきです。ただし、月は 0 から始まることに注意してください。
🎯 ベストプラクティス
💡 使用シナリオ推奨
Calendar コンポーネントは万能キーのようなもので、日付選択が必要な様々なシナリオに適しています:
🏨 ホテル予約システム
// チェックインとチェックアウトの日付を設定し、最小宿泊日数を制限
<van-calendar
type="range"
:min-date="new Date()"
:max-range="30"
:formatter="hotelFormatter"
/>📅 会議室予約
// 平日のみを選択可能にし、週末を除外
<van-calendar
type="multiple"
:formatter="workdayFormatter"
:min-date="new Date()"
/>🎂 誕生日リマインダー設定
// 単日選択で、過去の日付も選択可能
<van-calendar
type="single"
:max-date="new Date()"
title="誕生日を選択"
/>⚡ パフォーマンス最適化のヒント
- lazy-render の適切な使用:月数が多いカレンダーの場合、レイジーレンダリングを有効にするとパフォーマンスが大幅に向上します
- formatter の頻繁な更新を避ける:formatter 関数は安定したままにし、レンダリングごとに新しい関数を作成しないようにします
- switch-mode の使用:大量の月を表示する必要がある場合、フラットモードではなく切り替えモードを使用します
🎨 デザインの推奨事項
- カラーマッチング:ブランドの色調と調和するテーマカラーを選択し、あまり鮮やかな色を避けます
- ユーザーフレンドリーな文案:「日付選択」のようなユーザーに馴染みのある言語を使用します
- 迅速なフィードバック:ユーザーの操作後に視覚的なフィードバックをすぐに提供し、インタラクティブ体験を向上させます
🔗 関連コンポーネント
- DatePicker 日付ピッカー - 時分秒までの正確な日付時間選択に適しています
- Cell セル - トリガーとして Calendar と組み合わせてよく使用されます
- Popup ポップアップ - Calendar のポップアップモードはこのコンポーネントに基づいて実装されています
- Picker ピッカー - 日付選択の別のインタラクティブ方法
📚 拡張リーディング
💡 ヒント:Calendar コンポーネントは単なる日付選択ツールではなく、ユーザーエクスペリエンスを向上させる重要なコンポーネントです。その様々な機能を適切に活用することで、アプリをよりユーザーフレンドリーで専門的なものにすることができます!