Vant4 Calendar 日歷

2023-02-16 17:54 更新

介紹

日歷組件用于選擇日期或日期區(qū)間。

引入

通過以下方式來全局注冊(cè)組件,更多注冊(cè)方式請(qǐng)參考組件注冊(cè)

import { createApp } from 'vue';
import { Calendar } from 'vant';

const app = createApp();
app.use(Calendar);

代碼演示

選擇單個(gè)日期

下面演示了結(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,
    };
  },
};

選擇多個(gè)日期

設(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,
    };
  },
};

選擇日期區(qū)間

設(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ū)間最大范圍

選擇日期區(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' }"
/>

API

Props

參數(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

Calendar Poppable Props

當(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 -

Calendar Range Props

當(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

Calendar Multiple Props

當(dāng) Calendar 的 ?type? 為 ?multiple? 時(shí),支持以下 props:

參數(shù) 說明 類型 默認(rèn)值
max-range 日期最多可選天數(shù) number | string 無限制
range-prompt 選擇超過最多可選天數(shù)時(shí)的提示文案 string 最多選擇 xx 天

Day 數(shù)據(jù)結(jié)構(gòu)

日歷中的每個(gè)日期都對(duì)應(yīng)一個(gè) Day 對(duì)象,通過?formatter?屬性可以自定義 Day 對(duì)象的內(nèi)容

鍵名 說明 類型
date 日期對(duì)應(yīng)的 Date 對(duì)象 Date
type 日期類型,可選值為 selectedstart、middleend、disabled string
text 中間顯示的文字 string
topInfo 上方的提示信息 string
bottomInfo 下方的提示信息 string
className 額外類名 string

Events

事件名 說明 回調(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

Slots

名稱 說明 參數(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ù)?

如果需要在 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 系統(tǒng)上初始化組件失?。?/h3>

如果你遇到了在 iOS 上無法渲染組件的問題,請(qǐng)確認(rèn)在創(chuàng)建 Date 對(duì)象時(shí)沒有使用?new Date('2020-01-01')?這樣的寫法,iOS 不支持以中劃線分隔的日期格式,正確寫法是?new Date('2020/01/01')?。

對(duì)此問題的詳細(xì)解釋:stackoverflow。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)