Vuetify v-time-picker选择00时/分异常:事件参数验证失败
解决Vuetify v-time-picker选择00时/分的更新异常问题
问题核心
使用Vuetify的v-time-picker组件时,选择包含00的小时或分钟(如07:00)会触发Vue事件参数无效警告:
[Vue warn]: Invalid event arguments: event validation failed for event "input".
[Vue warn]: Invalid event arguments: event validation failed for event "change".
[Vue warn]: Invalid event arguments: event validation failed for event "update:minute".
这会导致状态管理仓库无法正确更新选中时间,组件需多次操作才能触发更新,且官方示例环境也可复现。
解决方案
方案1:改用Date类型绑定v-model(推荐)
Vuetify的v-time-picker原生更适配Date类型,能避免字符串格式转换时的类型不匹配问题:
<script setup lang="ts"> import { ref, onMounted, watch } from 'vue' import { useI18n } from 'vue-i18n' import { useTimeStore } from '@/stores/register' const { t } = useI18n() const timeStore = useTimeStore() // 改用Date类型绑定v-model const time = ref<Date>(new Date()) // 将Date格式化为"HH:mm"字符串 const formatTime = (date: Date): string => { const hours = String(date.getHours()).padStart(2, '0') const minutes = String(date.getMinutes()).padStart(2, '0') return `${hours}:${minutes}` } // 监听time变化,同步更新状态仓库 watch(time, (newDate) => { const formattedTime = formatTime(newDate) console.log('1) updateTime:', formattedTime) timeStore.setSelectedTime(formattedTime) }, { immediate: true }) onMounted(() => { // 初始化时已通过watch的immediate参数同步,无需重复调用 }) </script> <template> <v-responsive> <v-row justify="space-around"> <v-time-picker class="time-picker--container" v-model="time" format="24hr" scrollable :title="t('timePicker.title')" ></v-time-picker> </v-row> </v-responsive> </template>
方案2:保留字符串绑定,手动处理事件参数
如果必须使用字符串类型绑定,需要手动兼容update:modelValue的参数类型,确保传递给仓库的是正确格式的字符串:
<script setup lang="ts"> import { ref, onMounted } from 'vue' import { useI18n } from 'vue-i18n' import { useTimeStore } from '@/stores/register' const { t } = useI18n() const timeStore = useTimeStore() const time = ref('') const getCurrentTime = () => { const now = new Date() const hours = String(now.getHours()).padStart(2, '0') const minutes = String(now.getMinutes()).padStart(2, '0') return `${hours}:${minutes}` } const updateTime = (newTime: string | number) => { let formattedTime = '' // 处理参数为数字的情况(如选择00分钟时可能传入0) if (typeof newTime === 'number') { const currentHours = time.value.split(':')[0] formattedTime = `${currentHours}:${String(newTime).padStart(2, '0')}` } else { formattedTime = newTime } console.log('1) updateTime:', formattedTime) timeStore.setSelectedTime(formattedTime) // 同步更新v-model的值 time.value = formattedTime } onMounted(() => { const currentTime = getCurrentTime() time.value = currentTime timeStore.setSelectedTime(currentTime) }) </script> <template> <v-responsive> <v-row justify="space-around"> <v-time-picker class="time-picker--container" v-model="time" format="24hr" @update:modelValue="updateTime" scrollable :title="t('timePicker.title')" ></v-time-picker> </v-row> </v-responsive> </template>
原理说明
问题根源在于选择00时,组件可能传递数字0而非字符串"00",导致Vue的事件参数校验失败。改用Date类型绑定能让组件内部自动处理时间格式转换;若保留字符串绑定,则需手动兼容数字类型的参数,确保最终传递给状态仓库的是符合要求的字符串格式。
内容的提问来源于stack exchange,提问作者Walber Melo
相关产品推荐
相关产品推荐

