🧹 清理文件管理日期控件
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="native-date-strip" :aria-label="ariaLabel">
|
||||
<div class="native-date-strip" :class="fieldClass" :aria-label="ariaLabel">
|
||||
<select
|
||||
:value="parts.year"
|
||||
class="native-date-part native-date-year"
|
||||
@@ -30,6 +30,30 @@
|
||||
{{ day.toString().padStart(2, '0') }}
|
||||
</option>
|
||||
</select>
|
||||
<template v-if="includeTime">
|
||||
<span class="native-date-time-spacer" />
|
||||
<select
|
||||
:value="parts.hour"
|
||||
class="native-date-part native-date-time"
|
||||
:aria-label="`${ariaLabel}时`"
|
||||
@change="updatePart('hour', ($event.target as HTMLSelectElement).value)"
|
||||
>
|
||||
<option v-for="hour in hours" :key="hour" :value="hour">
|
||||
{{ hour.toString().padStart(2, '0') }}
|
||||
</option>
|
||||
</select>
|
||||
<span class="native-date-separator">:</span>
|
||||
<select
|
||||
:value="parts.minute"
|
||||
class="native-date-part native-date-time"
|
||||
:aria-label="`${ariaLabel}分`"
|
||||
@change="updatePart('minute', ($event.target as HTMLSelectElement).value)"
|
||||
>
|
||||
<option v-for="minute in minutes" :key="minute" :value="minute">
|
||||
{{ minute.toString().padStart(2, '0') }}
|
||||
</option>
|
||||
</select>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -43,12 +67,14 @@ const props = withDefaults(
|
||||
ariaLabel?: string
|
||||
minYear?: number
|
||||
maxYear?: number
|
||||
includeTime?: boolean
|
||||
}>(),
|
||||
{
|
||||
fieldClass: '',
|
||||
ariaLabel: '日期',
|
||||
minYear: 1900,
|
||||
maxYear: 2100
|
||||
maxYear: 2100,
|
||||
includeTime: false
|
||||
}
|
||||
)
|
||||
|
||||
@@ -57,7 +83,7 @@ const emit = defineEmits<{
|
||||
change: []
|
||||
}>()
|
||||
|
||||
type DatePart = 'year' | 'month' | 'day'
|
||||
type DatePart = 'year' | 'month' | 'day' | 'hour' | 'minute'
|
||||
|
||||
const pad = (value: number) => String(value).padStart(2, '0')
|
||||
const clamp = (value: number, min: number, max: number) => Math.max(min, Math.min(max, value))
|
||||
@@ -67,9 +93,13 @@ const years = computed(() =>
|
||||
Array.from({ length: props.maxYear - props.minYear + 1 }, (_, index) => props.minYear + index)
|
||||
)
|
||||
const months = Array.from({ length: 12 }, (_, index) => index + 1)
|
||||
const hours = Array.from({ length: 24 }, (_, index) => index)
|
||||
const minutes = Array.from({ length: 60 }, (_, index) => index)
|
||||
|
||||
const parts = computed(() => {
|
||||
const [rawYear, rawMonth, rawDay] = props.modelValue.split('-').map(Number)
|
||||
const [rawDate = '', rawTime = ''] = props.modelValue.split('T')
|
||||
const [rawYear, rawMonth, rawDay] = rawDate.split('-').map(Number)
|
||||
const [rawHour, rawMinute] = rawTime.split(':').map(Number)
|
||||
const year = clamp(Number.isFinite(rawYear) ? rawYear : new Date().getFullYear(), props.minYear, props.maxYear)
|
||||
const month = clamp(Number.isFinite(rawMonth) ? rawMonth : new Date().getMonth() + 1, 1, 12)
|
||||
const day = clamp(
|
||||
@@ -77,7 +107,9 @@ const parts = computed(() => {
|
||||
1,
|
||||
getDaysInMonth(year, month)
|
||||
)
|
||||
return { year, month, day }
|
||||
const hour = clamp(Number.isFinite(rawHour) ? rawHour : 0, 0, 23)
|
||||
const minute = clamp(Number.isFinite(rawMinute) ? rawMinute : 0, 0, 59)
|
||||
return { year, month, day, hour, minute }
|
||||
})
|
||||
|
||||
const days = computed(() =>
|
||||
@@ -90,7 +122,11 @@ const days = computed(() =>
|
||||
const updatePart = (part: DatePart, value: string) => {
|
||||
const next = { ...parts.value, [part]: Number(value) }
|
||||
next.day = clamp(next.day, 1, getDaysInMonth(next.year, next.month))
|
||||
emit('update:modelValue', `${next.year}-${pad(next.month)}-${pad(next.day)}`)
|
||||
const nextDate = `${next.year}-${pad(next.month)}-${pad(next.day)}`
|
||||
const nextValue = props.includeTime
|
||||
? `${nextDate}T${pad(next.hour)}:${pad(next.minute)}`
|
||||
: nextDate
|
||||
emit('update:modelValue', nextValue)
|
||||
emit('change')
|
||||
}
|
||||
</script>
|
||||
@@ -157,10 +193,16 @@ const updatePart = (part: DatePart, value: string) => {
|
||||
}
|
||||
|
||||
.native-date-month,
|
||||
.native-date-day {
|
||||
.native-date-day,
|
||||
.native-date-time {
|
||||
width: 2.2ch;
|
||||
}
|
||||
|
||||
.native-date-time-spacer {
|
||||
width: 0.9ch;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.native-date-separator {
|
||||
margin-inline: 0.35ch;
|
||||
color: #789096;
|
||||
|
||||
Reference in New Issue
Block a user