import { ref, computed } from 'vue' import { Field as VanField, Popup as VanPopup, Picker as VanPicker, DatetimePicker as VanDatetimePicker } from 'vant' import { formInputProps } from '../../form-input-props' import { useFormInput } from '../../../hooks/form-input' import dayjs from 'dayjs' import advancedFormat from 'dayjs/plugin/advancedFormat' import weekYear from 'dayjs/plugin/weekYear' import weekOfYear from 'dayjs/plugin/weekOfYear' dayjs.extend(advancedFormat) dayjs.extend(weekYear) dayjs.extend(weekOfYear) export default { props: formInputProps, setup (props, context) { const { width, clearable, placeholder, emitModelValue } = useFormInput(props, context) const show = ref(false) const openPicker = () => { show.value = true } const formatter = computed(() => { if (props.config?.formatter) { return props.config?.formatter } else { const typeToFormatter = { year: 'YYYY', month: 'YYYY-MM', week: 'YYYY 第 ww 周', date: 'YYYY-MM-DD', datetime: 'YYYY-MM-DD HH:mm:ss' } return typeToFormatter[type.value] ?? typeToFormatter.date } }) const type = computed(() => { const viewType = props.config?.viewType ?? 'date' return viewType.includes('range') ? 'date' : viewType }) // vant对dataType的特殊处理 const vantType = computed(() => { if (type.value === 'month') return 'year-month' return type.value }) const isTimestamp = computed(() => { return props.config?.isTimestamp ?? false }) // 展示的时间转换 const transValue = computed(() => { if (!props.modelValue) return null if (isTimestamp.value) { return dayjs(props.modelValue).format(formatter.value) } if (type.value === 'dates') { return props.modelValue.split(',') } return dayjs(props.modelValue).format(formatter.value) }) const pickerValue = computed(() => { return props.modelValue ? new Date(props.modelValue) : new Date() }) // 时间选择范围确定,最小时间和最大时间 const currentYear = new Date().getFullYear() const minDate = computed(() => { return props.config?.minDate ?? new Date(currentYear - 10, 0, 1) }) const maxDate = computed(() => { return props.config?.maxDate ?? new Date(currentYear + 10, 11, 31) }) // 确定按钮 const confirm = (value) => { show.value = false emitModelValue(typeToValue(value)) } // 取消按钮 const cancel = () => { show.value = false } // 不同事件类型传值不同,做转换 const typeToValue = (val) => { if (!val) return '' if (isTimestamp.value) { return new Date(val).getTime() } else if (type.value === 'datetime') { return dayjs(val).format('YYYY-MM-DD HH:mm:ss') } return dayjs(val).format(formatter.value) } // 年/月单独实现 const times = (n, iteratee) => { if (n < 0) return [] const result = new Array(n) let index = -1 while (++index < n) { result[index] = iteratee(index) } return result } // 月份前置0 const padZero = (num, targetLength = 2) => { let str = num + '' while (str.length < targetLength) { str = '0' + str } return str } // 年月的选项列表 const columns = computed(() => { const ranges = [ { type: 'year', range: [dayjs(minDate.value).format('YYYY'), dayjs(maxDate.value).format('YYYY')] } // { type: 'month', range: [dayjs(minDate.value).format('MM'), dayjs(maxDate.value).format('MM')] } ] const { range = null } = ranges.find(v => v.type === type.value) if (range) return times(range[1] - range[0] + 1, (index) => padZero(parseInt(range[0]) + index)) return [] }) // 年月的默认选中值设置 const defaultIndex = computed(() => { if (type.value === 'year') { return columns.value.findIndex(v => v === new Date().getFullYear().toString()) } if (type.value === 'month') { return columns.value.findIndex(v => v === new Date().getMonth().toString()) } return 0 }) // 头部标题配置 const titleMap = { year: '选择年', month: '选择年月', date: '选择年月日', datetime: '选择日期时间' } // 弹窗头部标题 const title = computed(() => { return titleMap[type.value] ?? titleMap.datetime }) return () =>
{['year'].includes(type.value) ? : }
} }