Vant4 Calendar 日歷

2023-02-16 17:54 更新

介紹

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

引入

通過以下方式來全局注冊組件,更多注冊方式請參考組件注冊。

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

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

代碼演示

選擇單個日期

下面演示了結(jié)合單元格來使用日歷組件的用法,日期選擇完成后會觸發(fā) ?confirm? 事件。

<van-cell title="選擇單個日期" :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? 后可以選擇多個日期,此時 ?confirm? 事件返回的 date 為數(shù)組結(jié)構(gòu),數(shù)組包含若干個選中的日期。

<van-cell title="選擇多個日期" :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} 個日期`;
    };

    return {
      text,
      show,
      onConfirm,
    };
  },
};

選擇日期區(qū)間

設(shè)置 ?type? 為 ?range? 后可以選擇日期區(qū)間,此時 ?confirm? 事件返回的 date 為數(shù)組結(jié)構(gòu),數(shù)組第一項為開始時間,第二項為結(jié)束時間。

<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è)置 allow-same-day 屬性來允許選擇同一天。

快捷選擇

將 ?show-confirm? 設(shè)置為 ?false? 可以隱藏確認(rèn)按鈕,這種情況下選擇完成后會立即觸發(fā) ?confirm? 事件。

<van-calendar v-model:show="show" :show-confirm="false" />

自定義顏色

通過 ?color? 屬性可以自定義日歷的顏色,對選中日期和底部按鈕生效。

<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è)置按鈕禁用時的文字。

<van-calendar
  v-model:show="show"
  type="range"
  confirm-text="完成"
  confirm-disabled-text="請選擇結(jié)束時間"
/>

自定義日期文案

通過傳入 ?formatter? 函數(shù)來對日歷上每一格的內(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 = '勞動節(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ū)間時,可以通過 ?max-range? 屬性來指定最多可選天數(shù),選擇的范圍超過最多可選天數(shù)時,會彈出相應(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?,日歷會直接展示在頁面內(nèi),而不是以彈層的形式出現(xiàn)。

<van-calendar
  title="日歷"
  :poppable="false"
  :show-confirm="false"
  :style="{ height: '500px' }"
/>

API

Props

參數(shù) 說明 類型 默認(rèn)值
type 選擇類型:
single 表示選擇單個日期,
multiple 表示選擇多個日期,
range 表示選擇日期區(qū)間
string single
title 日歷標(biāo)題 string 日期選擇
color 主題色,對底部按鈕和選中日期生效 string #1989fa
min-date 可選擇的最小日期 Date 當(dāng)前日期
max-date 可選擇的最大日期 Date 當(dāng)前日期的六個月后
default-date 默認(rèn)選中的日期,type 為 multiple 或 range 時為數(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)時的文字 string 確定
first-day-of-week 設(shè)置周起始日 0-6 0

Calendar Poppable Props

當(dāng) Calendar 的 ?poppable? 為 ?true? 時,支持以下 props:

參數(shù) 說明 類型 默認(rèn)值
v-model:show 是否顯示日歷彈窗 boolean false
position 彈出位置,可選值為 top right left string bottom
round 是否顯示圓角彈窗 boolean true
close-on-popstate 是否在頁面回退時自動關(guān)閉 boolean true
close-on-click-overlay 是否在點擊遮罩層后關(guān)閉 boolean true
safe-area-inset-top 是否開啟頂部安全區(qū)適配 boolean false
safe-area-inset-bottom 是否開啟底部安全區(qū)適配 boolean true
teleport 指定掛載的節(jié)點,等同于 Teleport 組件的 to 屬性 string | Element -

Calendar Range Props

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

參數(shù) 說明 類型 默認(rèn)值
max-range 日期區(qū)間最多可選天數(shù) number | string 無限制
range-prompt 范圍選擇超過最多可選天數(shù)時的提示文案 string 最多選擇 xx 天
show-range-prompt 范圍選擇超過最多可選天數(shù)時,是否展示提示文案 boolean true
allow-same-day 是否允許日期范圍的起止時間為同一天 boolean false

Calendar Multiple Props

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

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

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

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

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

Events

事件名 說明 回調(diào)參數(shù)
select 點擊并選中任意日期時觸發(fā) value: Date | Date[]
confirm 日期選擇完成后觸發(fā),若 show-confirm 為 true,則點擊確認(rèn)按鈕后觸發(fā) value: Date | Date[]
open 打開彈出層時觸發(fā) -
close 關(guān)閉彈出層時觸發(fā) -
opened 打開彈出層且動畫結(jié)束后觸發(fā) -
closed 關(guān)閉彈出層且動畫結(jié)束后觸發(fā) -
unselect 當(dāng)日歷組件的 type 為 multiple 時,取消選中日期時觸發(fā) value: Date
month-show 當(dāng)某個月份進(jìn)入可視區(qū)域時觸發(fā) { date: Date, title: string }
over-range 范圍選擇超過最多可選天數(shù)時觸發(fā) -
click-subtitle v3.1.3 點擊日歷副標(biāo)題時觸發(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 實例并調(diào)用實例方法,詳見組件實例方法。

方法名 說明 參數(shù) 返回值
reset 將選中的日期重置到指定日期,未傳參時會重置到默認(rèn)日期 date?: Date | Date[] -
scrollToDate 滾動到某個日期 date: Date -
getSelectedDate 獲取選中的日期 - Date | Date[] | null

類型定義

組件導(dǎo)出以下類型定義:

import type {
  CalendarType,
  CalendarProps,
  CalendarDayItem,
  CalendarDayType,
  CalendarInstance,
} from 'vant';

?CalendarInstance? 是組件實例的類型,用法如下:

import { ref } from 'vue';
import type { CalendarInstance } from 'vant';

const calendarRef = ref<CalendarInstance>();

calendarRef.value?.reset();

主題定制

樣式變量

組件提供了下列 CSS 變量,可用于自定義樣式,使用方法請參考 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ù),可以使用計算屬性動態(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 上無法渲染組件的問題,請確認(rèn)在創(chuàng)建 Date 對象時沒有使用?new Date('2020-01-01')?這樣的寫法,iOS 不支持以中劃線分隔的日期格式,正確寫法是?new Date('2020/01/01')?。

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


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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號