CalendarPro 日历
介绍
主要用于选择日期或日期区间,基于 vant 的组件进行二次封装。使用了以下组件:
引入
全局注册:
ts
import { createApp } from "vue"
import { CalendarPro } from "@dyb-dev/vant-pro"
const app = createApp()
app.use(CalendarPro)
1
2
3
4
5
2
3
4
5
代码演示
copy
源代码 ⬇️
<script setup lang="ts">
import { App, Button, Space } from "ant-design-vue"
import dayjs from "dayjs"
// @ts-ignore
import { Lunar } from "lunar-javascript"
import { reactive, ref } from "vue"
import { CalendarPro, showCalendarPro } from "@dyb-dev/vant-pro"
import CellPhoneBox from "@/components/CellPhoneBox.vue"
import JsonViewer from "@/components/JsonViewer.vue"
import type { TCalendarProSelectDate } from "@dyb-dev/vant-pro"
import type { CalendarDayItem } from "vant"
interface IData {
selectDate: TCalendarProSelectDate
}
/** REACTIVE: 数据 */
const data: IData = reactive({
selectDate: undefined
})
/** REF: 手机盒子实例 */
const cellPhoneBox = ref<InstanceType<typeof CellPhoneBox>>()
/** EVENT: 函数式调用 */
const onClickButton1 = async() => {
const _result = await showCalendarPro({
defaultDate: data.selectDate,
teleport: cellPhoneBox.value?.boxElement,
lockScroll: false,
formatter
})
if (_result[0]) {
data.selectDate = _result[0]
}
}
/** REF: 是否显示 */
const show = ref(false)
/** EVENT: 组件式调用 */
const onClickButton2 = async() => {
show.value = true
}
/**
* FUN: Calendar 格式化函数
*
* @param day 当前日期
* @returns 格式化后的日期
*/
const formatter = (day: CalendarDayItem) => {
// 如果有日期
if (day.date) {
// 根据当前时间 获取 lunar 对象
const _lunar = Lunar.fromDate(day.date)
// 获取阳历节日
const _solarFestival = _lunar.getSolar().getFestivals().join(",") || ""
// 获取农历节日
const _lunarFestival = _lunar.getFestivals().join(",") || ""
// 阳历节日优先显示,因为它们更为常见和重要
day.topInfo = _solarFestival || _lunarFestival
// 获取农历日
const _lunarDay = _lunar.getDayInChinese()
day.bottomInfo = _lunarDay
// 获取今天的 dayjs 对象
const _today = dayjs().startOf("day")
// 如果是今天,添加 '今天' 标记
if (dayjs(day.date).isSame(_today, "day")) {
day.text = "今天"
}
}
return day
}
</script>
<template>
<App>
<Space style="width: 100%" direction="vertical" size="middle">
<Space style="width: 100%" direction="horizontal">
<Button type="primary" @click="onClickButton1">函数式调用</Button>
<Button type="primary" @click="onClickButton2">组件式调用</Button>
</Space>
<CellPhoneBox ref="cellPhoneBox">
<CalendarPro
v-model:show="show"
v-model:select-date="data.selectDate"
type="range"
:show-confirm="true"
:lock-scroll="false"
:formatter="formatter"
/>
</CellPhoneBox>
<JsonViewer :value="data" :expand-depth="2" />
</Space>
</App>
</template>
API
vant-pro 中导出了 CalendarPro 相关的辅助函数:
方法名 | 说明 | 参数 | 返回值 |
---|---|---|---|
showCalendarPro | 显示日历弹窗,用户可以选择日期 | options?: TShowCalendarProOptions | Promise<TShowCalendarProResult> |
TShowCalendarProOptions
调用 showCalendarPro
等方法时,支持传入以下选项:
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
type | 选择类型:'single' 表示单选,'multiple' 表示多选,'range' 表示范围选择 | CalendarType | "single" |
switchMode | 切换模式:'none'、'month'、'year-month' | CalendarProps["switchMode"] | "year-month" |
title | 日历标题 | string | "日期选择" |
minDate | 可选择的最小日期 | Date | 2000/1/1 |
maxDate | 可选择的最大日期 | Date | 10年后 |
defaultDate | 默认选中的日期 | Date | Date[] | null | 今天 |
rowHeight | 日期行高 | number | string | 64 |
formatter | 日期格式化函数 | (day: CalendarDayItem) => CalendarDayItem | - |
lazyRender | 是否只渲染可视区域的内容 | boolean | true |
showMark | 是否显示月份背景水印 | boolean | true |
showTitle | 是否展示日历标题 | boolean | true |
showSubtitle | 是否展示日历副标题(年月) | boolean | true |
showConfirm | 是否展示确认按钮 | boolean | false |
readonly | 是否为只读状态,只读状态下不能选择日期 | boolean | false |
confirmText | 确认按钮的文字 | string | "确定" |
confirmDisabledText | 确认按钮处于禁用状态时的文字 | string | "确定" |
firstDayOfWeek | 设置周起始日,0 表示周日,1 表示周一 | TNumberRange<0, 6> | 1 |
maxRange | 日期区间最多可选天数(当 type 为 range、multiple 时有效) | number | string | 无限制 |
rangePrompt | 范围选择超过最多可选天数时的提示文案 | string | "最多选择 xx 天" |
showRangePrompt | 是否展示范围选择提示文案 | boolean | true |
allowSameDay | 是否允许日期范围的起止时间为同一天 | boolean | false |
lockScroll | 是否锁定背景滚动(当 poppable 为 true 时有效) | boolean | true |
teleport | 指定挂载的节点,等同于 Teleport 组件的 to 属性(当 poppable 为 true 时有效) | string | Element | - |
confirm | 点击确认按钮后触发 | (date: TCalendarProSelectDate) => void | - |
open | 打开弹出层时触发(当 poppable 为 true 时有效) | () => void | - |
close | 关闭弹出层时触发(当 poppable 为 true 时有效) | () => void | - |
opened | 打开弹出层且动画结束后触发(当 poppable 为 true 时有效) | () => void | - |
closed | 关闭弹出层且动画结束后触发(当 poppable 为 true 时有效) | () => void | - |
unselect | 当日历组件的 type 为 multiple 时,取消选中日期时触发 | (date: Date) => void | - |
monthShow | 当某个月份进入可视区域时触发 | (date: Date, title: string) => void | - |
overRange | 范围选择超过最多可选天数时触发 | () => void | - |
clickSubtitle | 点击日历副标题时触发 | (e: MouseEvent) => void | - |
clickDisabledDate | 点击禁用日期时触发 | (date: TCalendarProSelectDate) => void | - |
panelChange | 日历面板切换时触发 | (date: Date) => void | - |
Props
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
v-model:show | 是否显示 | boolean | - |
v-model:selectDate | 选择的日期,组件式调用时使用 | TCalendarProSelectDate | - |
type | 选择类型:'single' 表示单选,'multiple' 表示多选,'range' 表示范围选择 | CalendarType | "single" |
switchMode | 切换模式:'none'、'month'、'year-month' | CalendarProps["switchMode"] | "year-month" |
title | 日历标题 | string | "日期选择" |
minDate | 可选择的最小日期 | Date | 2000/1/1 |
maxDate | 可选择的最大日期 | Date | 10年后 |
defaultDate | 默认选中的日期,type 为 multiple 或 range 时为数组,传入 null 表示默认不选择 | Date | Date[] | null | 今天 |
rowHeight | 日期行高 | number | string | 64 |
formatter | 日期格式化函数 | (day: CalendarDayItem) => CalendarDayItem | - |
lazyRender | 是否只渲染可视区域的内容 | boolean | true |
showMark | 是否显示月份背景水印 | boolean | true |
showTitle | 是否展示日历标题 | boolean | true |
showSubtitle | 是否展示日历副标题(年月) | boolean | true |
showConfirm | 是否展示确认按钮 | boolean | false |
readonly | 是否为只读状态,只读状态下不能选择日期 | boolean | false |
confirmText | 确认按钮的文字 | string | "确定" |
confirmDisabledText | 确认按钮处于禁用状态时的文字 | string | "确定" |
firstDayOfWeek | 设置周起始日,0 表示周日,1 表示周一 | TNumberRange<0, 6> | 1 |
maxRange | 日期区间最多可选天数(当 type 为 range、multiple 时有效) | number | string | 无限制 |
rangePrompt | 范围选择超过最多可选天数时的提示文案 | string | "最多选择 xx 天" |
showRangePrompt | 是否展示范围选择提示文案 | boolean | true |
allowSameDay | 是否允许日期范围的起止时间为同一天 | boolean | false |
poppable | 是否以弹层的形式展示日历 | boolean | true |
lockScroll | 是否锁定背景滚动(当 poppable 为 true 时有效) | boolean | true |
teleport | 指定挂载的节点,等同于 Teleport 组件的 to 属性(当 poppable 为 true 时有效) | string | Element | - |
select | 点击并选中任意日期时触发 | (date: TCalendarProSelectDate) => void | - |
confirm | 点击确认按钮后触发 | (date: TCalendarProSelectDate) => void | - |
open | 打开弹出层时触发(当 poppable 为 true 时有效) | () => void | - |
close | 关闭弹出层时触发(当 poppable 为 true 时有效) | () => void | - |
opened | 打开弹出层且动画结束后触发(当 poppable 为 true 时有效) | () => void | - |
closed | 关闭弹出层且动画结束后触发(当 poppable 为 true 时有效) | () => void | - |
unselect | 当日历组件的 type 为 multiple 时,取消选中日期时触发 | (date: Date) => void | - |
monthShow | 当某个月份进入可视区域时触发 | (date: Date, title: string) => void | - |
overRange | 范围选择超过最多可选天数时触发 | () => void | - |
clickSubtitle | 点击日历副标题时触发 | (e: MouseEvent) => void | - |
clickDisabledDate | 点击禁用日期时触发 | (date: TCalendarProSelectDate) => void | - |
panelChange | 日历面板切换时触发 | (date: Date) => void | - |
Events
提示
下方展示的是新增的扩展选项,其他选项还请查看 Events
事件名 | 说明 | 回调参数 |
---|---|---|
update:selectDate | 选择的日期 | date: TCalendarProSelectDate |
类型定义
组件导出以下类型定义:
ts
import type {
TCalendarProSelectDate,
TCalendarProUnmountParam,
ICalendarProProps,
TShowCalendarProOptions,
TShowCalendarProResult
} from "@dyb-dev/vant-pro"
1
2
3
4
5
6
7
2
3
4
5
6
7
主题定制
请参考 vant 中 ConfigProvider 的使用