Skip to content
On this page

Calendar/CalendarPopup/CalendarView 日历

注:

Import

js
import { TaCalendar, TaCalendarPopup, TaCalendarView } from 'tantalum-ui-mobile'

具体的引入方式可以参考引入组件

Import Type

组件导出的类型定义:

ts
import type {
  CalendarValueFormatter,
  CalendarValueParser,
  CalendarOnSelect,
  CalendarOnConfirm,
  CalendarDayHandler,
  CalendarMode,
  CalendarDetail,
  SelectorOnChange,
  SelectorModelValue,
  VisibleState,
  PopupOnVisibleStateChange,
  PopupOnCancel
} from 'tantalum-ui-mobile'

公共 Props

属性类型默认值必填说明
v-modelSelectorModelValue[]选中值
min-dateDate当前日期可选最小值
max-dateDate当前日期的六个月后可选最大值
initial-modeCalendarMode'single'模式
allow-same-daybooleanfalserange 模式生效,设置开始结束时间是否可以同一天
max-rangenumber | stringInfinityrange 模式生效,选择区间的最长天数
day-handlerCalendarDayHandler日历每个日期处理函数
formatterCalendarValueFormatterparser 成对设置,对于 v-model 和 change 的值进行转化
parserCalendarValueParserformatter 成对设置,对于 v-model 和 change 的值进行反转化

Calendar 日历选择器

注:

  • 支持表单,具体可参考 Form
vue
<script setup lang="ts">
import { ref } from 'vue'
import dayjs from 'dayjs'
import { showToast, showCalendar, type SelectorModelValue } from '@/index'
import { formatter, parser, template } from '../Calendar/utils'

const simpleValue = ref([new Date()])
const rangeValue = ref([])
const formatValue = ref(dayjs().format(template))

const minDate = dayjs().startOf('day').subtract(1, 'month').toDate()
const maxDate = dayjs().startOf('day').add(1, 'month').toDate()

function onCallApi() {
  showCalendar({
    mode: 'range',
    showClose: true,
    success: res => {
      console.log('success', res)
      if (res.cancel) {
        showToast('取消了')
      } else {
        showToast(`选择了 ${res.detail.label}`)
      }
    }
  })
}

function onChange(res: SelectorModelValue) {
  console.log('change', res)

  showToast('change: ' + (res as any)[0])
}
</script>

<script lang="ts">
export default {
  name: 'ExpCalendar'
}
</script>

<template>
  <ta-group title="initialMode=simple">
    <ta-cell label="默认">
      <ta-calendar v-model="simpleValue" />
    </ta-cell>
    <ta-cell label="showConfirm=true">
      <ta-calendar showConfirm />
    </ta-cell>
    <ta-cell label="showClose=true">
      <ta-calendar showClose />
    </ta-cell>
    <ta-cell label="firstDayOfWeek=1">
      <ta-calendar :firstDayOfWeek="1" />
    </ta-cell>
    <ta-cell label="minDate/maxDate +-1month">
      <ta-calendar :minDate="minDate" :maxDate="maxDate" />
    </ta-cell>
    <ta-cell label="formatter/parser">
      <ta-calendar
        :formatter="formatter"
        :parser="parser"
        v-model="formatValue"
        @change="onChange"
      />
    </ta-cell>
    <ta-cell label="禁用">
      <ta-calendar v-model="simpleValue" disabled />
    </ta-cell>
  </ta-group>
  <ta-group title="initialMode=range">
    <ta-cell label="默认">
      <ta-calendar initialMode="range" v-model="rangeValue" />
    </ta-cell>
    <ta-cell label="allowSameDay">
      <ta-calendar initialMode="range" allowSameDay />
    </ta-cell>
    <ta-cell label="maxRange=5">
      <ta-calendar initialMode="range" :maxRange="5" />
    </ta-cell>
  </ta-group>
  <ta-group title="事件监听">
    <ta-cell label="change">
      <ta-calendar @change="onChange" />
    </ta-cell>
  </ta-group>
  <ta-group title="API">
    <ta-cell label="showCalendar" isLink @click="onCallApi()" />
  </ta-group>
</template>

Calendar Props

属性类型默认值必填说明
namestring标识
placeholderstring没有选中值的提示,也会用在弹窗标题上
disabledbooleanfalse是否禁用
show-confirmbooleanfalse弹窗是否展示确定按钮
show-closebooleanfalse弹窗是否展示关闭按钮

Calendar Events

事件描述回调函数参数函数 TypeScript
change选择后值发生改变时触发payload: SelectorModelValueSelectorOnChange

CalendarPopup 日历选择弹窗

vue
<script setup lang="ts">
import { ref } from 'vue'
import dayjs from 'dayjs'
import {
  showToast,
  type CalendarOnConfirm,
  type PopupOnVisibleStateChange,
  type PopupOnCancel,
  type SelectorModelValue
} from '@/index'
import { formatter, parser, template } from '../Calendar/utils'

const popupValue = ref(dayjs().format(template))
const popupRangeValue = ref([])

const popupVisible = ref(false)
const popupRangeVisible = ref(false)
const popupShowConfirm = ref(false)
const popupShowClose = ref(false)
const confirmEvent = ref(false)
const visibleEvent = ref(false)

const title = 'CalendarPopup'

const onVisibleStateChange: PopupOnVisibleStateChange = res => {
  if (visibleEvent.value) {
    console.log('change', res)
    showToast(`${res.state} 事件触发`)
  }

  if (res.state === 'hidden') {
    visibleEvent.value = false
    confirmEvent.value = false
    popupShowConfirm.value = false
    popupShowClose.value = false
  }
}

const onCancel: PopupOnCancel = res => {
  console.log('cancel', res)
  if (confirmEvent.value) {
    showToast(`触发了取消事件`)
  }
}

const onConfirm: CalendarOnConfirm = res => {
  console.log('confirm', res)
  if (confirmEvent.value) {
    showToast(`触发了确定事件`)
  }
}

function onChange(res: SelectorModelValue) {
  console.log('change', res)

  // showToast(`change: ${res}`)
}

const onRangeConfirm: CalendarOnConfirm = res => {
  console.log('confirm', res)
}

function addOneDay() {
  popupValue.value = dayjs(popupValue.value, template, true).add(1, 'day').format(template)
}
</script>

<script lang="ts">
export default {
  name: 'ExpCalendarPopup'
}
</script>

<template>
  <ta-notice-bar class="top-notice-bar" title="基础展示参数可以参考 Calendar" />
  <ta-group title="基础用法">
    <ta-cell
      label="默认"
      @click="
        () => {
          popupVisible = true
        }
      "
      >{{ popupValue }}</ta-cell
    >
    <ta-cell label="+1day" isLink @click="addOneDay">click</ta-cell>
    <ta-cell
      label="showConfirm=true"
      isLink
      @click="
        () => {
          popupShowConfirm = true
          popupVisible = true
        }
      "
    />
    <ta-cell label="initialMode=range" isLink @click="popupRangeVisible = true" />
  </ta-group>
  <ta-group title="事件监听">
    <ta-cell
      label="confirm/cancel"
      isLink
      @click="
        () => {
          confirmEvent = true
          popupVisible = true
          popupShowClose = true
        }
      "
    />
    <ta-cell
      label="visible-state-change"
      isLink
      @click="
        () => {
          visibleEvent = true
          popupVisible = true
        }
      "
    />
  </ta-group>
  <ta-calendar-popup
    v-model:visible="popupVisible"
    :title="title"
    :showConfirm="popupShowConfirm"
    :showClose="popupShowClose"
    v-model="popupValue"
    :formatter="formatter"
    :parser="parser"
    @confirm="onConfirm"
    @cancel="onCancel"
    @change="onChange"
    @visibleStateChange="onVisibleStateChange"
  />
  <ta-calendar-popup
    v-model:visible="popupRangeVisible"
    :title="title"
    initialMode="range"
    v-model="popupRangeValue"
    @confirm="onRangeConfirm"
  />
</template>

CalendarPopup Props

属性类型默认值必填说明
v-model:visiblebooleanfalse是否显示
titlestring弹窗标题
show-confirmbooleanfalse选择时是否展示确定按钮
show-closebooleanfalse是否展示关闭按钮

CalendarPopup Events

事件描述回调函数参数函数 TypeScript
confirm选择完毕后触发 / showConfirm 点击确定按钮后触发payload: CalendarDetailCalendarOnConfirm
cancel点击蒙层关闭后触发PopupOnCancel
change选择后值发生改变时触发payload: SelectorModelValueSelectorOnChange
visible-state-change展示隐藏时触发payload: { state: VisibleState }PopupOnVisibleStateChange

VisibleState 值说明

说明备注
show展示时触发
shown展示且动画结束后触发
hide隐藏时触发可能携带其他参数 cancel, maskClick, closeClick 等
hidden隐藏且动画结束后触发可能携带其他参数 cancel, maskClick, closeClick 等

CalendarView 日历选择面板

vue
<script setup lang="ts">
import { ref } from 'vue'
import { type CalendarOnSelect, showToast } from '@/index'
import { formatter, parser } from '../Calendar/utils'

const viewValue = ref('')
const viewRangeValue = ref('')

const onSelect: CalendarOnSelect = res => {
  console.log('select', res)

  showToast(`选择:${res.label}`)
}
</script>

<script lang="ts">
export default {
  name: 'ExpCalendarView'
}
</script>

<template>
  <ta-notice-bar class="top-notice-bar" title="基础展示参数可以参考 Calendar" />
  <ta-group title="initialMode=single">
    <ta-cell label="v-model"> {{ viewValue }} </ta-cell>
    <ta-calendar-view v-model="viewValue" :formatter="formatter" :parser="parser" />
  </ta-group>
  <ta-group title="initialMode=range">
    <ta-cell label="v-model"> {{ viewRangeValue }} </ta-cell>
    <ta-calendar-view
      initialMode="range"
      v-model="viewRangeValue"
      :formatter="formatter"
      :parser="parser"
    />
  </ta-group>
  <ta-group title="select 事件">
    <ta-calendar-view @select="onSelect" />
  </ta-group>
</template>

CalendarView Events

事件描述回调函数参数函数 TypeScript
select选择后触发payload: CalendarDetailCalendarOnSelect
change选择后值发生改变时触发payload: SelectorModelValueSelectorOnChange

showCalendar(object) 显示日历选择弹窗

object

属性类型默认值必填说明
modeCalendarMode'single'模式
titlestring弹窗标题
valueDate/Date[][]默认选择值,range 模式下需要提供两个
minDateDate当前日期可选最小值
maxDateDate当前日期的六个月后可选最大值
allowSameDaybooleanfalserange 模式生效,设置开始结束时间是否可以同一天
maxRangenumberInfinityrange 模式生效,选择区间的最长天数
dayHandlerCalendarDayHandler日历每个日期处理函数
success(payload: SuccessPayload) => void接口调用成功(在用户做出选择后,如取消,选择选项)的回调函数
fail(e: Error) => void接口调用失败(如传入错误的参数)的回调函数(不传入 fail 遇错误直接抛出)
complete() => void弹窗关闭或调用失败的回调函数

SuccessPayload

属性类型说明
confirm?boolean为 true 时,表示点击了确定,此时返回 detail
cancel?boolean为 true 时,表示取消
detail?CalendarDetail

Usage

具体调用方式可以参考API 调用

js
showCalendar({
  type: 'range',
  showClose: true,
  success: ({ confirm, cancel, detail }) => {
    ...
  }
})

类型释义

SelectorValue

ts
type SelectorValue = string | number | Date

SelectorModelValue

ts
type SelectorModelValue = SelectorValue | SelectorValue[]

注:在不自定义 formatter/parser 的情况下,v-model 只有 Date[] 这种情况。

CalendarDetail

ts
interface CalendarDetail {
  label: string
  value: Date[]
  valueArray: number[][]
  rangeCount: number
}
字段说明
label选中值对应的描述文本,如果设置了 formatter,则返回格式后文本
value选择的值,range 模式下有开始 Date 和结束 Date 两个实例,不受 formatter 影响
valueArray如:[[2021, 5, 1]] 或 [[2021, 5, 1], [2021, 5, 30]]
rangeCount选择区间持续的天数(含首尾)

CalendarMode

ts
type CalendarMode = 'single' | 'range'
说明
single选择一天
range选择一个日期区间

CalendarValueFormatter

ts
interface CalendarValueFormatter {
  (valueArray: Date[], mode: CalendarMode):
    | { value: SelectorModelValue; label: string }
    | SelectorModelValue
}

将 v-model 的原始值转为需要的自定义值,值需要满足 SelectorModelValue 的类型约束,可以返回 { value, label } 对两个数据进行修改,或者单独返回 value。

CalendarValueParser

ts
interface CalendarValueParser {
  (value: unknown, mode: CalendarMode): Date[]
}

CalendarValueFormatter 相反,将自定义 v-model 的值转为组件认识的原始数组。

CalendarDayHandler

ts
type CalendarDayHandler = dayHandler(dayInfo: DayInfo) => DayInfo

interface DayInfo {
  topHighlight?: boolean
  topText?: string
  state: string
  bottomHighlight?: boolean
  bottomText?: string
  text: string
  dateString: string
  date?: Date
  timestamp: number
}

日历中的每个日期都对应一个 DayInfo 对象,通过 day-handler 属性可以修改 DayInfo 对象的内容后返回。

类型说明
dateDate日期对应的 Date 对象,该字段修改无效
statestring日期当前的状态,有:selected 选中,startSelected 开始(initialMode="range"下),endSelected 结束(initialMode="range"下),disabled 禁用。在空字符串的情况下,可以设置为 disabled 强制设置该日期为禁用(一般在票卖完的情况下设置)
textstring日期文本,不建议修改
topTextstring日期上方展示文本,一般可修改为“节日名称”、“今天”、“明天”、“开始”、“结束”等
topHighlightboolean日期上方展示文本是否高亮
bottomTextstring日期下方展示文本,一般可修改为“机票价格”、“酒店价格”、“特价”、“热门”等
bottomHighlightboolean日期下方展示文本是否高亮
dateStringstring日期对应的格式化时间(YYYY-MM-DD),如:2020-11-11,该字段不影响展示