美文网首页
vant 封装时间段选择器

vant 封装时间段选择器

作者: 请叫我彭彭 | 来源:发表于2021-11-15 10:44 被阅读0次

组件代码

<template>
  <van-popup v-model:show="props.visible" position="bottom" @close="closePopup">
    <van-picker v-bind="$attrs" :columns="columns" @change="onChange" @confirm="onConfirm" @cancel="closePopup" />
  </van-popup>
</template>

<script lang="ts" setup>
import dayjs from 'dayjs'
import { ref, computed } from 'vue'

interface props {
  /** 窗口是否显示 */
  visible: boolean
  /** 时间段 */
  times?: string[]
  /** 分割符 */
  apart?: string
  /** 最大时间 */
  maxTime?: number
  /** 最小时间 */
  minTime?: number
  /** 最大分钟数 */
  maxMinute?: number
  /** 最小分钟数 */
  minMinute?: number
}

interface timeType {
  /** 开始时间 */
  startTime: string
  /** 开始分钟 */
  startMinute: string
  /** 结束时间  */
  endTime: string
  /** 结束分钟 */
  endMinute: string
}

/** 最终返回的结果 */
const timeValue = ref<string>('')

const props = withDefaults(defineProps<props>(), {
  apart: '~',
  maxTime: 12,
  minTime: 1,
  maxMinute: 59,
  minMinute: 1,
  times: () => {
    return [dayjs().format('HH-mm'), dayjs().format('HH-mm')]
  }
})

const emit = defineEmits<{
  (e: 'update:visible', value: Boolean): void
  (e: 'confirm', value: string): void
}>()

/** 配置列 */
interface column {
  values: string[] | number[] | string
  defaultIndex: number
}

/** 时段 */
const months: string[] = []
for (let i = props.minTime; i <= props.maxTime; i++) {
  months.push((i + '').padStart(2, '0'))
}

/** 分钟 */
const days: string[] = []
for (let i = props.minMinute; i <= props.maxMinute; i++) {
  days.push((i + '').padStart(2, '0'))
}

/** 得到最终的格式 */
const timeResult = computed(() => {
  if (props.times.length !== 2) throw new Error('时间格式错误')
  /** 开始时间 分秒*/
  const startTimes = props.times[0].split('-')
  /** 结束时间 分秒 */
  const endTimes = props.times[1].split('-')

  if (startTimes.length !== 2) throw new Error('开始时间格式错误')
  else if (endTimes.length != 2) throw new Error('结束时间错误')

  return {
    startTime: startTimes[0],
    startMinute: startTimes[1],
    endTime: endTimes[0],
    endMinute: endTimes[1]
  } as timeType
})

const columns = ref<column[]>([
  {
    values: months, // 开始时
    defaultIndex: Number(timeResult.value.startTime) - 1
  },
  {
    values: days, // 开始分
    defaultIndex: Number(timeResult.value.startMinute) - 1
  },
  {
    values: [props.apart], // 分割符
    defaultIndex: 0
  },
  {
    values: months, // 结束时
    defaultIndex: Number(timeResult.value.endTime) - 1
  },
  {
    values: days, // 结束分
    defaultIndex: Number(timeResult.value.endMinute) - 1
  }
])

/** 选择时间段取消事件 */
function closePopup() {
  emit('update:visible', false)
}

/** 选择时间段确认事件 */
function onConfirm() {
  if (timeValue.value) {
    emit('confirm', timeValue.value)
  } else {
    emit('confirm', `${props.times[0]}${props.apart}${props.times[1]}`)
  }
  closePopup()
}

/** 选择时间段值改变事件 */
function onChange(values: string[]) {
  const reg = new RegExp(`-${props.apart}-`)
  const result = values.join('-').replace(reg, props.apart)
  timeValue.value = result
}
</script>
<style scoped lang="scss"></style>

代码示例

<template>
  <PickerTime v-model:visible="chooseDateVisible" title="请选择预约时间" @confirm="onTimeConfirm" />
<template>
<script lang="ts" setup>
import { ref} from 'vue'
import PickerTime from './components/PickerTime '
 const chooseDateVisible = ref(false)
/** 选择时间段确认事件 */
function onTimeConfirm(value: string) {
  console.log(value)
}
</script>

ui效果

image.png

具体文档参考vant-picktime,继承了vant-picker的所有属性

相关文章

网友评论

      本文标题:vant 封装时间段选择器

      本文链接:https://www.haomeiwen.com/subject/pjzftrtx.html