日歷組件用于選擇日期或日期區(qū)間。
通過以下方式來全局注冊(cè)組件,更多注冊(cè)方式請(qǐng)參考組件注冊(cè)。
import { createApp } from 'vue';
import { Calendar } from 'vant';
const app = createApp();
app.use(Calendar);
下面演示了結(jié)合單元格來使用日歷組件的用法,日期選擇完成后會(huì)觸發(fā) ?confirm
? 事件。
<van-cell title="選擇單個(gè)日期" :value="date" @click="show = true" />
<van-calendar v-model:show="show" @confirm="onConfirm" />
import { ref } from 'vue';
export default {
setup() {
const date = ref('');
const show = ref(false);
const formatDate = (date) => `${date.getMonth() + 1}/${date.getDate()}`;
const onConfirm = (value) => {
show.value = false;
date.value = formatDate(value);
};
return {
date,
show,
onConfirm,
};
},
};
設(shè)置 ?type
? 為 ?multiple
? 后可以選擇多個(gè)日期,此時(shí) ?confirm
? 事件返回的 date 為數(shù)組結(jié)構(gòu),數(shù)組包含若干個(gè)選中的日期。
<van-cell title="選擇多個(gè)日期" :value="text" @click="show = true" />
<van-calendar v-model:show="show" type="multiple" @confirm="onConfirm" />
import { ref } from 'vue';
export default {
setup() {
const text = ref('');
const show = ref(false);
const onConfirm = (dates) => {
show.value = false;
text.value = `選擇了 ${dates.length} 個(gè)日期`;
};
return {
text,
show,
onConfirm,
};
},
};
設(shè)置 ?type
? 為 ?range
? 后可以選擇日期區(qū)間,此時(shí) ?confirm
? 事件返回的 date 為數(shù)組結(jié)構(gòu),數(shù)組第一項(xiàng)為開始時(shí)間,第二項(xiàng)為結(jié)束時(shí)間。
<van-cell title="選擇日期區(qū)間" :value="date" @click="show = true" />
<van-calendar v-model:show="show" type="range" @confirm="onConfirm" />
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: 默認(rèn)情況下,日期區(qū)間的起止時(shí)間不能為同一天,可以通過設(shè)置 allow-same-day 屬性來允許選擇同一天。
將 ?show-confirm
? 設(shè)置為 ?false
? 可以隱藏確認(rèn)按鈕,這種情況下選擇完成后會(huì)立即觸發(fā) ?confirm
? 事件。
<van-calendar v-model:show="show" :show-confirm="false" />
通過 ?color
? 屬性可以自定義日歷的顏色,對(duì)選中日期和底部按鈕生效。
<van-calendar v-model:show="show" color="#ee0a24" />
通過 ?min-date
? 和 ?max-date
? 定義日歷的范圍。
<van-calendar v-model:show="show" :min-date="minDate" :max-date="maxDate" />
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
? 設(shè)置按鈕文字,通過 ?confirm-disabled-text
? 設(shè)置按鈕禁用時(shí)的文字。
<van-calendar
v-model:show="show"
type="range"
confirm-text="完成"
confirm-disabled-text="請(qǐng)選擇結(jié)束時(shí)間"
/>
通過傳入 ?formatter
? 函數(shù)來對(duì)日歷上每一格的內(nèi)容進(jìn)行格式化。
<van-calendar v-model:show="show" type="range" :formatter="formatter" />
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 = '勞動(dòng)節(jié)';
} else if (date === 4) {
day.topInfo = '青年節(jié)';
} 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" :round="false" position="right" />
選擇日期區(qū)間時(shí),可以通過 ?max-range
? 屬性來指定最多可選天數(shù),選擇的范圍超過最多可選天數(shù)時(shí),會(huì)彈出相應(yīng)的提示文案。
<van-calendar type="range" :max-range="3" :style="{ height: '500px' }" />
通過 ?first-day-of-week
? 屬性設(shè)置一周從哪天開始。
<van-calendar first-day-of-week="1" />
將 ?poppable
? 設(shè)置為 ?false
?,日歷會(huì)直接展示在頁面內(nèi),而不是以彈層的形式出現(xiàn)。
<van-calendar
title="日歷"
:poppable="false"
:show-confirm="false"
:style="{ height: '500px' }"
/>
參數(shù) | 說明 | 類型 | 默認(rèn)值 |
---|---|---|---|
type | 選擇類型:
single 表示選擇單個(gè)日期,
multiple 表示選擇多個(gè)日期,
range 表示選擇日期區(qū)間 |
string | single
|
title | 日歷標(biāo)題 | string | 日期選擇
|
color | 主題色,對(duì)底部按鈕和選中日期生效 | string | #1989fa
|
min-date | 可選擇的最小日期 | Date | 當(dāng)前日期 |
max-date | 可選擇的最大日期 | Date | 當(dāng)前日期的六個(gè)月后 |
default-date | 默認(rèn)選中的日期,type 為 multiple 或 range 時(shí)為數(shù)組,傳入 null 表示默認(rèn)不選擇 |
Date | Date[] | null | 今天 |
row-height | 日期行高 | number | string | 64
|
formatter | 日期格式化函數(shù) | (day: Day) => Day | - |
poppable | 是否以彈層的形式展示日歷 | boolean | true
|
lazy-render | 是否只渲染可視區(qū)域的內(nèi)容 | boolean | true
|
show-mark | 是否顯示月份背景水印 | boolean | true
|
show-title | 是否展示日歷標(biāo)題 | boolean | true
|
show-subtitle | 是否展示日歷副標(biāo)題(年月) | boolean | true
|
show-confirm | 是否展示確認(rèn)按鈕 | boolean | true
|
readonly | 是否為只讀狀態(tài),只讀狀態(tài)下不能選擇日期 | boolean | false
|
confirm-text | 確認(rèn)按鈕的文字 | string | 確定
|
confirm-disabled-text | 確認(rèn)按鈕處于禁用狀態(tài)時(shí)的文字 | string | 確定
|
first-day-of-week | 設(shè)置周起始日 | 0-6 | 0
|
當(dāng) Calendar 的 ?poppable
? 為 ?true
? 時(shí),支持以下 props:
參數(shù) | 說明 | 類型 | 默認(rèn)值 |
---|---|---|---|
v-model:show | 是否顯示日歷彈窗 | boolean | false
|
position | 彈出位置,可選值為 top right left
|
string | bottom
|
round | 是否顯示圓角彈窗 | boolean | true
|
close-on-popstate | 是否在頁面回退時(shí)自動(dòng)關(guān)閉 | boolean | true
|
close-on-click-overlay | 是否在點(diǎn)擊遮罩層后關(guān)閉 | boolean | true
|
safe-area-inset-top | 是否開啟頂部安全區(qū)適配 | boolean | false
|
safe-area-inset-bottom | 是否開啟底部安全區(qū)適配 | boolean | true
|
teleport | 指定掛載的節(jié)點(diǎn),等同于 Teleport 組件的 to 屬性 | string | Element | - |
當(dāng) Calendar 的 ?type
? 為 ?range
? 時(shí),支持以下 props:
參數(shù) | 說明 | 類型 | 默認(rèn)值 |
---|---|---|---|
max-range | 日期區(qū)間最多可選天數(shù) | number | string | 無限制 |
range-prompt | 范圍選擇超過最多可選天數(shù)時(shí)的提示文案 | string | 最多選擇 xx 天
|
show-range-prompt | 范圍選擇超過最多可選天數(shù)時(shí),是否展示提示文案 | boolean | true
|
allow-same-day | 是否允許日期范圍的起止時(shí)間為同一天 | boolean | false
|
當(dāng) Calendar 的 ?type
? 為 ?multiple
? 時(shí),支持以下 props:
參數(shù) | 說明 | 類型 | 默認(rèn)值 |
---|---|---|---|
max-range | 日期最多可選天數(shù) | number | string | 無限制 |
range-prompt | 選擇超過最多可選天數(shù)時(shí)的提示文案 | string | 最多選擇 xx 天
|
日歷中的每個(gè)日期都對(duì)應(yīng)一個(gè) Day 對(duì)象,通過?formatter
?屬性可以自定義 Day 對(duì)象的內(nèi)容
鍵名 | 說明 | 類型 |
---|---|---|
date | 日期對(duì)應(yīng)的 Date 對(duì)象 | Date |
type | 日期類型,可選值為 selected 、start 、middle 、end 、disabled
|
string |
text | 中間顯示的文字 | string |
topInfo | 上方的提示信息 | string |
bottomInfo | 下方的提示信息 | string |
className | 額外類名 | string |
事件名 | 說明 | 回調(diào)參數(shù) |
---|---|---|
select | 點(diǎn)擊并選中任意日期時(shí)觸發(fā) | value: Date | Date[] |
confirm | 日期選擇完成后觸發(fā),若 show-confirm 為 true ,則點(diǎn)擊確認(rèn)按鈕后觸發(fā) |
value: Date | Date[] |
open | 打開彈出層時(shí)觸發(fā) | - |
close | 關(guān)閉彈出層時(shí)觸發(fā) | - |
opened | 打開彈出層且動(dòng)畫結(jié)束后觸發(fā) | - |
closed | 關(guān)閉彈出層且動(dòng)畫結(jié)束后觸發(fā) | - |
unselect | 當(dāng)日歷組件的 type 為 multiple 時(shí),取消選中日期時(shí)觸發(fā) |
value: Date |
month-show | 當(dāng)某個(gè)月份進(jìn)入可視區(qū)域時(shí)觸發(fā) | { date: Date, title: string } |
over-range | 范圍選擇超過最多可選天數(shù)時(shí)觸發(fā) | - |
click-subtitle v3.1.3
|
點(diǎn)擊日歷副標(biāo)題時(shí)觸發(fā) | event: MouseEvent |
名稱 | 說明 | 參數(shù) |
---|---|---|
title | 自定義標(biāo)題 | - |
subtitle v3.1.3
|
自定義日歷副標(biāo)題 | { text: string, date?: Date } |
footer | 自定義底部區(qū)域內(nèi)容 | - |
confirm-text v3.2.6
|
自定義確認(rèn)按鈕的內(nèi)容 | { disabled: boolean } |
top-info v3.0.17
|
自定義日期上方的提示信息 | day: Day |
bottom-info v3.0.17
|
自定義日期下方的提示信息 | day: Day |
通過 ref 可以獲取到 Calendar 實(shí)例并調(diào)用實(shí)例方法,詳見組件實(shí)例方法。
方法名 | 說明 | 參數(shù) | 返回值 |
---|---|---|---|
reset | 將選中的日期重置到指定日期,未傳參時(shí)會(huì)重置到默認(rèn)日期 | date?: Date | Date[] | - |
scrollToDate | 滾動(dòng)到某個(gè)日期 | date: Date | - |
getSelectedDate | 獲取選中的日期 | - | Date | Date[] | null |
組件導(dǎo)出以下類型定義:
import type {
CalendarType,
CalendarProps,
CalendarDayItem,
CalendarDayType,
CalendarInstance,
} from 'vant';
?CalendarInstance
? 是組件實(shí)例的類型,用法如下:
import { ref } from 'vue';
import type { CalendarInstance } from 'vant';
const calendarRef = ref<CalendarInstance>();
calendarRef.value?.reset();
組件提供了下列 CSS 變量,可用于自定義樣式,使用方法請(qǐng)參考 ConfigProvider 組件。
名稱 | 默認(rèn)值 | 描述 |
---|---|---|
--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-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-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-info-font-size | var(--van-font-size-xs) | - |
--van-calendar-info-line-height | var(--van-line-height-xs) | - |
--van-calendar-selected-day-background | var(--van-primary-color) | - |
--van-calendar-day-disabled-color | var(--van-text-color-3) | - |
--van-calendar-confirm-button-height | 36px | - |
--van-calendar-confirm-button-margin | 7px 0 | - |
如果需要在 formatter 中使用異步返回的數(shù)據(jù),可以使用計(jì)算屬性動(dòng)態(tài)創(chuàng)建 formatter 函數(shù),示例如下:
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 上無法渲染組件的問題,請(qǐng)確認(rèn)在創(chuàng)建 Date 對(duì)象時(shí)沒有使用?new Date('2020-01-01')
?這樣的寫法,iOS 不支持以中劃線分隔的日期格式,正確寫法是?new Date('2020/01/01')
?。
對(duì)此問題的詳細(xì)解釋:stackoverflow。
更多建議: