Skip to content

Calendar 日历

介绍

日历组件用于选择日期,支持单选、范围选择和多选模式,可用于表单组件中。

导入

js
import Calendar from '@/components/form/Calendar.vue'
import CalendarField from '@/components/form/CalendarField.vue'

用法

基础用法

可以单独使用 Calendar 组件作为日历展示日期。日历默认会显示农历与几个固定节假日。

vue
<template>
  <FlexCol :radius="20" backgroundColor="white" :padding="30">
    <Calendar v-model="value1" />
  </FlexCol>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import Calendar from '@/components/form/Calendar.vue'
import FlexCol from '@/components/layout/FlexCol.vue'

const value1 = ref('')
</script>

选择用法

支持单选(day)、范围(range)、多选(days)三种选择模式。

vue
<template>
  <div>
    <Calendar v-model="value2" :pickType="value2Type" />
    <FlexCol :gap="20">
      <FlexRow center :padding="15">
        <text>选中日期:{{ value2Text }}</text>
      </FlexRow>
      <FlexRow align="center">
        <RadioGroup v-model="value2Type">
          <Radio name="day" text="单选" />
          <Radio name="range" text="范围" />
          <Radio name="days" text="多选" />
        </RadioGroup>
      </FlexRow>
    </FlexCol>
  </div>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'
import Calendar from '@/components/form/Calendar.vue'
import Radio from '@/components/form/Radio.vue'
import RadioGroup from '@/components/form/RadioGroup.vue'
import FlexCol from '@/components/layout/FlexCol.vue'
import FlexRow from '@/components/layout/FlexRow.vue'
import type { CalendarPickType } from '@/components/form/Calendar.vue'

const value2 = ref([])
const value2Type = ref<CalendarPickType>('day')

const value2Text = computed(() => {
  if (typeof value2.value === 'string')
    return value2.value
  if (value2.value.length === 2)
    return value2.value.join(' 至 ')
  else
    return value2.value.join(', ')
})
</script>

弹出用法

可调用已封装好的弹出层组件 CalendarField 中使用。

vue
<template>
  <CellGroup round>
    <Cell title="选择日期" touchable showArrow>
      <template #value>
        <CalendarField v-model="value3" />
      </template>
    </Cell>
    <Cell title="选择日期区间" touchable showArrow>
      <template #value>
        <CalendarField 
          v-model="value4"
          pickType="range" 
          :pickStateText="[ '入店', '离店' ]"
          shouldUpdateValueImmediately
        >
          <template #footer>
            <FlexCol center :padding="20">
              <Text v-if="value4.length < 2" color="text.second">请选择入住日期,单次最长预定10日</Text>
              <Text v-else color="text.second">共 {{ value4Days }} 天</Text>
            </FlexCol>
          </template>
        </CalendarField>
      </template>
    </Cell>
  </CellGroup>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'
import { DateUtils } from '@imengyu/imengyu-utils'
import CalendarField from '@/components/form/CalendarField.vue'
import Cell from '@/components/basic/Cell.vue'
import CellGroup from '@/components/basic/CellGroup.vue'
import FlexCol from '@/components/layout/FlexCol.vue'
import Text from '@/components/basic/Text.vue'

const value3 = ref([])
const value4 = ref([])

const value4Days = computed(() => {
  if (value4.value.length < 2)
    return 0
  const start = DateUtils.parseDate(value4.value[0])
  const end = DateUtils.parseDate(value4.value[1])
  return DateUtils.getDayDiff(start, end)
})
</script>

快捷选择

在单选或者范围模式下,选择完成后直接关闭。

vue
<template>
  <CellGroup round>
    <Cell title="选择日期" touchable showArrow>
      <template #value>
        <CalendarField v-model="value6" autoConfirm />
      </template>
    </Cell>
    <Cell title="选择日期区间" touchable showArrow>
      <template #value>
        <CalendarField 
          v-model="value7"
          pickType="range" 
          :pickStateText="[ '入店', '离店' ]"
          autoConfirm
        />
      </template>
    </Cell>
  </CellGroup>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import CalendarField from '@/components/form/CalendarField.vue'
import Cell from '@/components/basic/Cell.vue'
import CellGroup from '@/components/basic/CellGroup.vue'

const value6 = ref('')
const value7 = ref([])
</script>

自定义样式

可以自定义选中颜色、特定日期颜色和附加文字。

vue
<template>
  <CellGroup round>
    <Cell title="自定义选中和特定日期颜色" touchable showArrow>
      <template #value>
        <ProvideVar :vars="{
          CalendarItemColorSelected: 'danger',
          CalendarItemColorSelectedInRange: 'mask.danger',
        }">
          <CalendarField 
            v-model="value8" 
            :dayTextProps="{
              fontSize: 37,
              fontWeight: 'bold',
            }"
            :daysTextProps="value9DaysTextProps"
          />
        </ProvideVar>
      </template>
    </Cell>
    <Cell title="自定义日期附加和选中文字" touchable showArrow>
      <template #value>
        <CalendarField 
          v-model="value9"
          pickType="range" 
          :pickStateText="[ '入店', '离店' ]"
          :extraDayStrings="value9ExtraDayStrings"
          :daysTextProps="value9DaysTextProps"
        />
      </template>
    </Cell>
  </CellGroup>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { DateUtils } from '@imengyu/imengyu-utils'
import CalendarField from '@/components/form/CalendarField.vue'
import Cell from '@/components/basic/Cell.vue'
import CellGroup from '@/components/basic/CellGroup.vue'
import ProvideVar from '@/components/theme/ProvideVar.vue'
import type { CalendarProps } from '@/components/form/Calendar.vue'

const value8 = ref('')
const value9 = ref([])

const now = new Date()
const value9DaysTextProps = ref<CalendarProps['daysTextProps']>({
  [DateUtils.formatDate(now, 'yyyy-MM-dd')]: {
    color: 'danger',
    fontWeight: 'bold',
  },
})
const value9ExtraDayStrings = ref<CalendarProps['extraDayStrings']>({
  [DateUtils.formatDate(now, 'yyyy-MM-dd')]: {
    text: '优惠日!',
    textProps: {
      color: 'danger',
    },
    topText: '三折!',
    topTextProps: {
      color: 'danger',
    }
  },
})
</script>

平铺展示

可以将月份平铺滚动展示,建议只显示最近的几个月,显示过多月份易卡顿。

vue
<template>
  <CellGroup round>
    <Cell title="平铺选择日期" touchable showArrow>
      <template #value>
        <CalendarField 
          v-model="value6" 
          scrollMode
          startDate="2025-01-01"
          endDate="2025-12-31"
        />
      </template>
    </Cell>
    <Cell title="平铺选择日期区间" touchable showArrow>
      <template #value>
        <CalendarField 
          v-model="value7"
          pickType="range" 
          :pickStateText="[ '入店', '离店' ]"
          :maxPickRangeDays="20"
          scrollMode
          startDate="2025-01-01"
          endDate="2025-12-31"
        />
      </template>
    </Cell>
  </CellGroup>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import CalendarField from '@/components/form/CalendarField.vue'
import Cell from '@/components/basic/Cell.vue'
import CellGroup from '@/components/basic/CellGroup.vue'

const value6 = ref('')
const value7 = ref([])
</script>

API 参考

Calendar

日历组件。

Props

名称说明类型必填默认值
modelValue选择的日期string[] | string--
currentMonth进入时当前日历显示的月份Date-当前月份
topMonthFormat顶部月份的格式string-'yyyy年MM月'
scrollMode可以将月份平铺滚动展示boolean-false
scrollModePageHeight滚动模式下,每页的高度number-360
scrollModePages滚动模式下,滚动容器高度,即显示几页number-2
dateFormat日期格式string-'yyyy-MM-dd'
pickType选择模式:day(选择一天)、range(选择范围)、days(选择多天)'day'|'range'|'days'-'day'
pickStateText设置选择后在日期按钮上的状态文本string|string[]--
startDate限制开始日期string-5年前
endDate限制结束日期string-10年后
itemProps条目的自定义属性FlexProps--
showFestival是否展示固定节日boolean-true
extraDayStrings在日期上、下方显示自定义文字Record<string, { text: string; textProps?: TextProps; topText?: string; topTextProps?: TextProps }>--
disabledDates设置不可选的日期string[]--
maxPickRangeDays最大可选天数,仅在模式为 days, range 时生效number-0
weekTexts自定义周文字string[]-['日', '一', '二', '三', '四', '五', '六']
headerTextProps自定义头部日期文字的样式TextProps--
dayTextProps自定义日期文字的样式TextProps--
daysTextProps自定义单个日期文字的样式Record<string, TextProps>--
backgroundTextProps自定义背景文字的样式TextProps--

Events

名称说明参数
update:modelValue更新选择的日期string | string[]
pickOverMaxDays超出最大可选天数时触发-
selectTextChange选择文本改变时触发string

CalendarField

日历弹出层组件。

Props

名称说明类型必填默认值
modelValue
选择的日期
string|string[]--
title标题string-'请选择日期'
titleProps标题属性Omit<ActionSheetTitleProps, 'title'>-{ cancelText: '取消', confirmText: '确定' }
showSelectText是否显示选择的文本boolean-true
placeholder占位符string-'请选择日期'
initalValue初始值string[]--
shouldUpdateValueImmediately是否在选择完成后立即更新值boolean-false
textProps显示的文本属性TextProps--
autoConfirm是否在单选或者范围模式下,选择完成后直接关闭boolean-false
beforeConfirm确认前的回调(value: string|string[]|undefined) => Promise<boolean>--

Slots

名称说明
footer底部插槽

Events

名称说明参数
update:modelValue更新选择的日期string | string[]
cancel取消选择时触发-
confirm确认选择时触发string | string[]
selectTextChange选择文本改变时触发string
tempValueChange临时值改变时触发string | string[]

主题变量

名称类型默认值说明
CalendarItemColorNormalstringtransparent日历项正常状态颜色
CalendarItemColorSelectedstringprimary日历项选中状态颜色
CalendarItemColorSelectedInRangestringmask.primary日历项选中范围内颜色
CalendarItemColorDisabledstringtransparent日历项禁用状态颜色
CalendarTextColorDisabledstringtext.second日历禁用文本颜色
CalendarTextColorNormalstringtext.content日历正常文本颜色
CalendarTextColorNormalWeekendstringdanger日历周末文本颜色
CalendarTextColorSelectedstringwhite日历选中文本颜色
CalendarTextColorSelectedInRangestringprimary日历选中范围内文本颜色
CalendarTopTextSizenumber22日历顶部文本大小
CalendarTextSizenumber30日历主体文本大小
CalendarBottomTextSizenumber22日历底部文本大小