概述
<b-calendar>
符合 WAI-ARIA 無障礙標準,針對鍵盤控制進行了最佳化(箭頭、向上/向下翻頁、首頁和結束鍵)。它也支援國際化,並且預設使用瀏覽器或頁面的語言環境,如果沒有指定語言環境的話。
如果你需要一個日期選取器作為自訂的表單控制輸入元件,可以改用 <b-form-datepicker>
元件。
<template>
<b-row>
<b-col md="auto">
<b-calendar v-model="value" @context="onContext" locale="en-US"></b-calendar>
</b-col>
<b-col>
<p>Value: <b>'{{ value }}'</b></p>
<p class="mb-0">Context:</p>
<pre class="small">{{ context }}</pre>
</b-col>
</b-row>
</template>
<script>
export default {
data() {
return {
value: '',
context: null
}
},
methods: {
onContext(ctx) {
this.context = ctx
}
}
}
</script>
v-model
回傳值
預設情況下,<b-calendar>
以 YYYY-MM-DD
格式的字串傳回日期,而這是原生瀏覽器 <input type="date">
控制項所傳回的格式。您可以透過設定 value-as-date
屬性,讓 <b-calendar>
傳回 Date
物件(無時間區段),作為 v-model
值。
如果未選取任何日期,<b-calendar>
會傳回空字串 ''
,或者如果設定 value-as-date
屬性,則傳回 null
。
請注意,當設定 value-as-date
屬性時,傳回的 Date
物件將使用瀏覽器預設的時區。
停用和唯讀狀態
設定 disabled
屬性,將移除 <b-calendar>
元件的所有互動性。
設定 readonly
屬性,將停用日期選取功能,但會讓元件持續保持互動性,允許日期導覽。v-model
狀態將不會在唯讀狀態下更新。
如要停用特定日期或設定最小和最大日期限制,請參閱 日期約束 部分。
<template>
<div>
<b-form-group label="Select calendar interactive state" v-slot="{ ariaDescribedby }">
<b-form-radio-group
v-model="state"
:aria-describedby="ariaDescribedby"
aria-controls="ex-disabled-readonly"
>
<b-form-radio value="disabled">Disabled</b-form-radio>
<b-form-radio value="readonly">Readonly</b-form-radio>
<b-form-radio value="normal">Normal</b-form-radio>
</b-form-radio-group>
</b-form-group>
<b-calendar
id="ex-disabled-readonly"
:disabled="disabled"
:readonly="readonly"
></b-calendar>
</div>
</template>
<script>
export default {
data() {
return {
state: 'disabled'
}
},
computed: {
disabled() {
return this.state === 'disabled'
},
readonly() {
return this.state === 'readonly'
}
}
}
</script>
日期約束
最小和最大日期
透過 min
和 max
屬性來限制行事曆範圍。這些屬性接受 YYYY-MM-DD
格式的日期字串或 Date
物件。
<template>
<div>
<b-calendar v-model="value" :min="min" :max="max" locale="en"></b-calendar>
</div>
</template>
<script>
export default {
data() {
const now = new Date()
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate())
const minDate = new Date(today)
minDate.setMonth(minDate.getMonth() - 2)
minDate.setDate(15)
const maxDate = new Date(today)
maxDate.setMonth(maxDate.getMonth() + 2)
maxDate.setDate(15)
return {
value: '',
min: minDate,
max: maxDate
}
}
}
</script>
停用日期
如果需要在行事曆中停用特定日期,請指定 date-disabled-fn
屬性的一個函數參照。這個函數會傳入兩個參數:
ymd
作為 YYYY-MM-DD
字串的日期 date
作為 Date
物件的日期
如果日期無法選取(停用),則函數應傳回 true
;如果日期可以選取(啟用),則應傳回 false
。請注意,這個函數無法進行非同步處理,應盡快回傳值。
<template>
<div>
<b-calendar v-model="value" :date-disabled-fn="dateDisabled" locale="en"></b-calendar>
</div>
</template>
<script>
export default {
data() {
return {
value: ''
}
},
methods: {
dateDisabled(ymd, date) {
const weekday = date.getDay()
const day = date.getDate()
return weekday === 0 || weekday === 6 || day === 13
}
}
}
</script>
請注意,min
和 max
日期約束會在 date-disabled-fn
之前進行評估。
樣式設定
變體
選取的日期按鈕(背景顏色)的預設為 'primary'
主題變型。您可以使用 selected-variant
屬性將其變更為任何 Bootstrap v4 主題變型的顏色:'secondary'
、'success'
、'danger'
、'warning'
、'info'
等。
預設情況下,今日的日期也會使用與選取日期相同的變體突出顯示(文字顏色)。如要指定不同的主題顏色來使用在今日的日期,請使用 today-variant
屬性。
如要完全停用今日日期的突出顯示,請設定 no-highlight-today
屬性。
導航按鈕的預設為 'secondary'
主題變型。您可以透過 nav-button-variant
屬性變更這項設定。
<template>
<b-calendar
selected-variant="success"
today-variant="info"
nav-button-variant="primary"
></b-calendar>
</template>
寬度
<b-calendar>
會以內嵌區塊元素呈現,預設寬度為 270px
(不包括新增的任何內補或邊框)。此寬度已優化,以便放入較小的行動裝置中。
如要變更寬度,請將 width
屬性設定為任何有效的 CSS 寬度(包括單位)。
除了透過設定 block
屬性,使行事曆為全寬,並使其展開符合父元素的寬度。當設定 block
時,width
屬性不會有效果。
<template>
<b-calendar block locale="en-US"></b-calendar>
</template>
請注意,不建議設定低於 260px
的寬度,否則可能會造成此元件的截斷和配置問題。
初始開啟行事曆日期
預設情況下,當未選取任何日期時,行事曆檢視會設定為目前月份(或 min
或 max
日期,如果今日日期超過 min
或 max
的範圍)。您可以透過 initial-date
屬性指定日期來更改此行為。初始日期屬性將用來決定初始顯示使用者的行事曆月份。它不會設定元件的值。
v2.6.0 以上
如要變更元件中顯示日期文字的格式選項,例如在標題中,請將 date-format-options
屬性設定為包含要求的格式屬性的物件,適用於 Intl.DateTimeFormat
物件(另請參閱 國際化)。
<template>
<div>
<p>Custom date format:</p>
<b-calendar
:date-format-options="{ year: 'numeric', month: 'short', day: '2-digit', weekday: 'short' }"
locale="en"
></b-calendar>
<p class="mt-3">Short date format:</p>
<b-calendar
:date-format-options="{ year: 'numeric', month: 'numeric', day: 'numeric' }"
locale="en"
></b-calendar>
</div>
</template>
下表摘要了每個格式屬性的有效選項
屬性 | 可能的值 |
年 | '數值' 或 '2 位數字' |
月份 | '數值' 、'2 位數字' 、'長' 、'短' 或 '窄' |
日期 | '數值' 或 '2 位數字' |
星期 | '長' 、'短' 或 '窄' |
備註
- 略過某些選項可能會影響格式化的文字字串,例如,
星期
- 格式化的值會依據已解決的區域設定而有所不同。有些區域設定可能不支援
'窄'
格式,且會改用 '短'
或 長'
(如果沒有提供 '短'
) 年
、月
和 日
始終會顯示。如果您需要略過值,請將該屬性設定為 未定義
,儘管這在助於無障礙的原因考量之下極不建議
2.12.0+
預設的星期名稱標題格式為 '短'
,這通常為星期名稱的 3 個字元縮寫,儘管有些 區域設定 可能會覆寫此項目。格式可透過 Prop 星期-標題-格式
控制並接受三個值中的其中一個
'長'
完整星期名稱 (例如 星期二)。在使用全寬月曆時相當方便。請避免與預設月曆寬度搭配使用。 '短'
通常為星期名稱的 2 或 3 個字母縮寫,依據所選區域設定而定 (例如「二」)。 '窄'
通常為 1 個字元的縮寫 (例如 二)。有些區域設定的兩天星期風格可能相同 (例如星期二和星期四的窄式風格都是 星期二)。這對於不支援 '短'
格式的區域設定相當方便,例如區域設定 'ar'
和 'fa'
。
預設情況下,目前已選取的日期會顯示在月曆元件的頂部,並以區域設定的語言格式化。
您可以透過 隱藏-標題
Prop 隱藏此標題。請注意這僅會以視覺方式隱藏已選取的日期,同時讓螢幕朗讀程式使用者可以透過一個 aria-live
區域取得相關資訊。
有關用法範例,請參閱以下 國際化 部分。
設定 show-decade-nav
屬性,以在日曆的日期導覽工具列中啟用前一個與下一個十年的按鈕。
可以使用 label-prev-decade
和 label-next-decade
屬性提供十年按鈕自訂標籤文字。
有關用法範例,請參閱以下 國際化 部分。
外框和內距
想要有內距外框的日曆嗎?使用 Bootstrap 的 外框和內距工具類別 新增外框和內距
<template>
<b-calendar class="border rounded p-2" locale="en"></b-calendar>
</template>
預設插槽
使用預設插槽,在日曆介面的底部提供選用內容。插槽可用於新增按鈕,例如 Select Today
或 Reset
等。
<template>
<b-calendar v-model="value" value-as-date locale="en">
<div class="d-flex" dir="ltr">
<b-button
size="sm"
variant="outline-danger"
v-if="value"
@click="clearDate"
>
Clear date
</b-button>
<b-button
size="sm"
variant="outline-primary"
class="ml-auto"
@click="setToday"
>
Set Today
</b-button>
</div>
</b-calendar>
</template>
<script>
export default {
data() {
return {
value: null
}
},
methods: {
setToday() {
const now = new Date()
this.value = new Date(now.getFullYear(), now.getMonth(), now.getDate())
},
clearDate() {
this.value = ''
}
}
}
</script>
2.12.0+
若要變更日曆的日期導覽按鈕內容,BootstrapVue 為每個按鈕提供範圍插槽
'nav-prev-decade'
'nav-prev-year'
'nav-prev-month'
'nav-this-month'
(移至選取/今日按鈕) 'nav-next-month'
'nav-next-year'
'nav-next-decade'
全部七個插槽都有相同的範圍屬性可供使用
屬性 | 類型 | 說明 |
isRTL | 布林值 | 當日期導覽列從右至左呈現時,將為 true |
可以使用 isRTL
範圍屬性「翻轉」上一個與下一個按鈕內容,以處理從左至右到從右至左的方向變更,亦即當 isRTL
為 true
時,上一年按鈕將位於右側,而非左側。
為特定日期新增 CSS 類別
如果您需要突顯特定日期,請將 date-info-fn
屬性設定為函式的參照,此函式會傳回要套用在日期儲存格的 CSS 類別字串(或字串陣列)。函式會傳遞兩個引數
ymd
作為 YYYY-MM-DD
字串的日期 date
作為 Date
物件的日期
此函式可以傳回字串或字串陣列。如果沒有要設定的類別,可以傳回空白字串 (''
)、空白陣列 ([]
) 或 null
。
在此範例中,我們使用 table-{variant}
顏色類別,在日期儲存格中設定背景顏色。 table-{variant}
顏色類別效果良好,因為它們是主題顏色的柔和版本。
<template>
<div>
<b-calendar v-model="value" :date-info-fn="dateClass" locale="en"></b-calendar>
</div>
</template>
<script>
export default {
data() {
return {
value: ''
}
},
methods: {
dateClass(ymd, date) {
const day = date.getDate()
return day >= 10 && day <= 20 ? 'table-info' : ''
}
}
}
</script>
請注意,已停用的日期不會呼叫函式。
輔助功能注意事項
當使用類別值傳達日期的特定意義時,您應該在日曆之外 (或透過預設區域格) 納入額外的脈絡,說明浮顯的日期 (例如在 aria-live
區域),特別是對於螢幕閱讀器使用者。
BootstrapVue 未來可能會新增一項功能,透過這個功能在浮顯的日期新增螢幕閱讀器友善的文字說明。
事件
在更新 v-model
時會產生 'input'
事件。事件會有一個單一引數,即選取的日期。預設值是一個 YYYY-MM-DD
格式的字串 (或如果沒有選取日期時會是一個空字串)。如果設定 value-as-date
屬性,則第一個引數將會是一個 Date
物件 (或如果沒有選取日期時會是 null
)。
如果 disabled
或 readonly
屬性已被設定,則 'input'
事件將不會產生。
selected
事件
使用者點選一個未停用的日期時會產生 'selected'
事件。事件會傳遞兩個引數
ymd
以 YYYY-MM-DD
格式表示的選取日期為字串 date
以 Date
物件表示的選取日期
如果使用者點選已選取的日期,仍然會產生 selected
事件,這與會不會再次產生已選取日期的 'input'
事件相反。
如果 disabled
或 readonly
屬性已被設定,則 'selected'
事件將不會產生。
context
事件
每當使用者選取某個日期,或使用者瀏覽日曆時 (透過游標鍵、向上/向下頁鍵、首頁或結束鍵,或使用日曆瀏覽按鈕) 就會產生 'context'
事件。在元件建立 (插入 DOM 之前) 或已解析的區域設定已變更時也會產生該事件。
當 readonly
屬性已被設定時,當使用者瀏覽日曆時仍然會產生該事件。如果 disabled
屬性已被設定,則不會產生該事件 (在建立日曆時的初始產生事件除外)。
傳遞 'context'
事件一個內容物件當作它唯一的引數,內容物件具有下列的屬性。
屬性 | 說明 |
selectedYMD | 選取的日期值(YYYY-MM-DD 格式)或若未選取日期,則會傳回空字串。 |
selectedDate | 選取的日期值,用 Date 物件表示,或者若未選取日期,則傳回 null 。 |
selectedFormatted | 依據目前的語言環境對選取日期進行格式化。若未選取日期,則會傳回 label-no-date-selected 屬性的值。 |
activeYMD | 可以用字串表示,做為目前日曆按鈕的日期,並接收 YYYY-MM-DD 格式的焦點。 |
activeDate | 可以用 Date 物件表示,做為目前日曆按鈕的日期,並接收焦點。 |
activeFormatted | 依據目前的語言環境對活動日期進行格式化。 |
disabled | 若是目前的日期遭停用,則傳回 true ,否則傳回 false 。 |
locale | 已解決的語言環境 (可能與要求的語言環境不同)。 |
calendarLocale | 由日曆解決並使用的語言環境,可以選擇是否包括日曆類型 (例如:'gregory')。通常這與 locale 相同,但可能會包括所使用的日曆類型,例如選擇波斯語系語言環境 ('fa' ) 時,會選用 fa-u-ca-gregory 。 |
isRTL | 若日曆以 RTL(從右到左)方向顯示,則傳回 true 。若以 LTR(從左到右)顯示,則傳回 false 。 |
若要透過 Intl.DateTimeFormat
手動格式化日期,請使用 calendarLocale
屬性值,而非 locale
屬性值,以確保使用與 <b-calendar>
所用相同的日曆慣例。對於未完整實作 Intl.DateTimeFormat
所有功能的 IE 11 瀏覽器,這項設定特別重要。有關更多詳細資訊,請參閱下列 國際化章節。
國際化
除了應用於日曆控制元件元素的標籤(aria-標籤,選定狀態和說明文字)之外,日曆的國際化是由 Intl.DateTimeFormat
提供的。對於這些標籤,你必須提供自己的翻譯。可用的語言環境會因瀏覽器而異(並非所有瀏覽器都支援所有語言環境)。
預設情況下,<b-calendar>
會採用瀏覽器的預設語言環境,但您可以透過 locale
屬性來指定要使用的語言環境(或多個語言環境)。此屬性接受單一語言環境字串,或陣列的語言環境字串(依據偏好的語言環境順序排列)。
日曆週從星期日開始。這可以透過設定 start-weekday
屬性為介於 0
至 6
範圍內的數字來改變,其中 0
代表星期日,1
代表星期一,直到 6
代表星期六。
發出的 context
事件將包含日曆解析出的語言環境(依據 Intl
的支援語言環境,此語言環境可能與要求的語言環境不同)。
<template>
<b-row>
<b-col cols="12" class="mb-3">
<label for="example-locales">Locale:</label>
<b-form-select id="example-locales" v-model="locale" :options="locales"></b-form-select>
<label for="example-weekdays" class="mt-2">Start weekday:</label>
<b-form-select id="example-weekdays" v-model="weekday" :options="weekdays"></b-form-select>
<b-form-checkbox v-model="showDecadeNav" switch inline class="my-2">
Show decade navigation buttons
</b-form-checkbox>
<b-form-checkbox v-model="hideHeader" switch inline class="my-2">
Hide the date header
</b-form-checkbox>
</b-col>
<b-col md="auto">
<b-calendar
v-model="value"
v-bind="labels[locale] || {}"
:locale="locale"
:start-weekday="weekday"
:hide-header="hideHeader"
:show-decade-nav="showDecadeNav"
@context="onContext"
></b-calendar>
</b-col>
<b-col>
<p>Value: <b>'{{ value }}'</b></p>
<p class="mb-0">Context:</p>
<pre class="small">{{ context }}</pre>
</b-col>
</b-row>
</template>
<script>
export default {
data() {
return {
value: '',
context: null,
showDecadeNav: false,
hideHeader: false,
locale: 'en-US',
locales: [
{ value: 'en-US', text: 'English US (en-US)' },
{ value: 'de', text: 'German (de)' },
{ value: 'ar-EG', text: 'Arabic Egyptian (ar-EG)' },
{ value: 'zh', text: 'Chinese (zh)' }
],
weekday: 0,
weekdays: [
{ value: 0, text: 'Sunday' },
{ value: 1, text: 'Monday' },
{ value: 6, text: 'Saturday' }
],
labels: {
de: {
labelPrevDecade: 'Vorheriges Jahrzehnt',
labelPrevYear: 'Vorheriges Jahr',
labelPrevMonth: 'Vorheriger Monat',
labelCurrentMonth: 'Aktueller Monat',
labelNextMonth: 'Nächster Monat',
labelNextYear: 'Nächstes Jahr',
labelNextDecade: 'Nächstes Jahrzehnt',
labelToday: 'Heute',
labelSelected: 'Ausgewähltes Datum',
labelNoDateSelected: 'Kein Datum gewählt',
labelCalendar: 'Kalender',
labelNav: 'Kalendernavigation',
labelHelp: 'Mit den Pfeiltasten durch den Kalender navigieren'
},
'ar-EG': {
weekdayHeaderFormat: 'narrow',
labelPrevDecade: 'العقد السابق',
labelPrevYear: 'العام السابق',
labelPrevMonth: 'الشهر السابق',
labelCurrentMonth: 'الشهر الحالي',
labelNextMonth: 'الشهر المقبل',
labelNextYear: 'العام المقبل',
labelNextDecade: 'العقد القادم',
labelToday: 'اليوم',
labelSelected: 'التاريخ المحدد',
labelNoDateSelected: 'لم يتم اختيار تاريخ',
labelCalendar: 'التقويم',
labelNav: 'الملاحة التقويم',
labelHelp: 'استخدم مفاتيح المؤشر للتنقل في التواريخ'
},
zh: {
weekdayHeaderFormat: 'narrow',
labelPrevDecade: '过去十年',
labelPrevYear: '上一年',
labelPrevMonth: '上个月',
labelCurrentMonth: '当前月份',
labelNextMonth: '下个月',
labelNextYear: '明年',
labelNextDecade: '下一个十年',
labelToday: '今天',
labelSelected: '选定日期',
labelNoDateSelected: '未选择日期',
labelCalendar: '日历',
labelNav: '日历导航',
labelHelp: '使用光标键浏览日期'
}
}
}
},
methods: {
onContext(ctx) {
this.context = ctx
}
}
}
</script>
目前 <b-calendar>
僅支援格里歷('gregory'
)日曆。
預設情況下,<b-calendar>
會透過已解析的語言環境自動偵測從右到左或從左到右。您可以透過設定 direction
屬性為字串 rtl
來強制日曆從右到左顯示,或設定 direction
屬性為 'ltr'
來強制日曆始終從左到右顯示。
您可以偵聽 context
事件來判斷日曆解析出的語言環境和方向性。
對於使用 Node.js 的伺服器端呈現 (SSR),請確保您所使用的 Node.js 執行時期支援 Intl
和您將使用的語言環境。請參閱 Node Intl
支援文件 以深入了解詳情。
無障礙
<b-calendar>
提供許多無障礙功能,例如:aria-live
區域、角色、aria 標記、快速鍵和完整的鍵盤導覽,以搭配大多數螢幕閱讀器使用。
鍵盤導覽
- 向左鍵 移至前一天(或在 RTL 模式中移至後一天)
- 向右鍵 移至後一天(或在 RTL 模式中移至前一天)
- 向上鍵 移至前一週的同一天
- 向下鍵 移至下一週的同一天
- 向上翻頁 移至前一個月的同一天
- 向下翻頁 移至下一個月的同一天
- Alt+向上翻頁 移至前一年的同一天和月份
- Alt+PageDown 移動到下一年的同一天份
- Ctrl+Alt+PageUp 移動到前一個十年的同一天份
- Ctrl+Alt+PageDown 移動到下一個十年的同一天份
- Home 移動到今天的日期
- End 移動到目前選取的日期,如果沒有選取日期則移動到今天
- Enter 或 Space 選取目前高亮(焦點)的日期
多數 label-*
props 在畫面中不可見,而是用於標記日曆中各種元素以供螢幕閱讀器使用者使用。例如, label-today
props 加到包含今日日期的單元格,'一月 28 日, 2020 (今天)'
,而 label-selected
props 加到包含選取日期的單元格 '一月 28 日, 2020 (選取日期)'
並作為 sr-only
文字加到選取日期標題中。
在對日期選擇器國際化時,更新 label-*
props 並使用適當的翻譯字串非常重要,以便讓國際螢幕使用者可以聽到正確的提示與說明。
<b-calendar>
的功能與樣式設計上刻意保持簡約,以便讓所有 使用者都能盡可能地輕鬆使用。
實作注意事項
<b-calendar>
使用 Bootstrap 的邊框和彈性工具類別,以及按鈕 (btn-*
) 類別與 form-control
類別。適當的樣式也需要 BootstrapVue 的自訂 SCSS/CSS。
在無障礙方面,我們選擇不 使用日曆的 ARIA 角色 grid
,以減少冗餘並在各種螢幕閱讀器(NVDA 中,在遇到角色 grid
時,會將焦點單元格讀成「選取」,這可能會誤導使用者)中提供一致性。
另請參閱