如何在Vuetify的v-text-field中实现天:时:分格式的输入?
Great question! The native type="time" attribute used by Vuetify's v-text-field only supports hour:minute:second formatting due to browser limitations, so it can't be directly modified to include days. But don't worry—there are two reliable, user-friendly ways to implement the day:hour:minute format you need.
1. Custom Text Input with Formatting & Validation
This approach uses a standard text field with custom logic to handle input formatting and validation, giving you full control over the input structure.
Here's a complete example:
<template> <v-text-field label="Day:Hour:Minute" v-model="formattedTime" :rules="[validateTimeFormat]" placeholder="e.g. 3:05:45" variant="outlined" ></v-text-field> </template> <script> export default { data() { return { // Store raw values for easy manipulation timeData: { days: 0, hours: 0, minutes: 0 }, }; }, computed: { // Convert raw data to display format, and parse input back to raw data formattedTime: { get() { return `${this.timeData.days}:${ String(this.timeData.hours).padStart(2, '0') }:${String(this.timeData.minutes).padStart(2, '0')}`; }, set(inputValue) { const parts = inputValue.split(':'); if (parts.length === 3) { this.timeData = { days: parseInt(parts[0]) || 0, hours: Math.max(0, Math.min(23, parseInt(parts[1]) || 0)), minutes: Math.max(0, Math.min(59, parseInt(parts[2]) || 0)), }; } }, }, }, methods: { // Ensure input matches day:hh:mm format validateTimeFormat(value) { const timeRegex = /^\d+:[0-5]\d:[0-5]\d$/; return timeRegex.test(value) || 'Please enter a valid format: day:hh:mm'; }, }, }; </script>
Key Benefits:
- Mimics the single-input experience of the native time field
- Includes validation to prevent invalid entries
- Automatically clamps hours/minutes to valid ranges (0-23 for hours, 0-59 for minutes)
2. Multi-Component Input (Better UX for Precise Entry)
If you want to eliminate manual input errors entirely, use separate number inputs for days, hours, and minutes, then combine their values into a single formatted string.
Example implementation:
<template> <v-row align="center" wrap> <v-number-input label="Days" v-model="timeData.days" min="0" class="mr-3" style="max-width: 120px;" ></v-number-input> <span class="text-h5 font-weight-bold">:</span> <v-number-input label="Hours" v-model="timeData.hours" min="0" max="23" class="mx-3" style="max-width: 120px;" ></v-number-input> <span class="text-h5 font-weight-bold">:</span> <v-number-input label="Minutes" v-model="timeData.minutes" min="0" max="59" class="ml-3" style="max-width: 120px;" ></v-number-input> <!-- Optional: Display combined formatted value --> <v-text-field label="Combined Time" :value="formattedTime" readonly class="mt-4 ml-0" variant="outlined" ></v-text-field> </v-row> </template> <script> export default { data() { return { timeData: { days: 0, hours: 0, minutes: 0 }, }; }, computed: { formattedTime() { return `${this.timeData.days}:${ String(this.timeData.hours).padStart(2, '0') }:${String(this.timeData.minutes).padStart(2, '0')}`; }, }, }; </script>
Key Benefits:
- No manual typing required—users just adjust numbers
- Built-in range validation for hours/minutes
- Clear, intuitive UI that reduces user error
Important Notes
- The native
type="time"input is constrained by browser APIs, so extending it to support days isn't possible. Custom solutions are the only way forward. - When submitting data to a backend, you can either send the formatted string (
"3:05:45") or convert the rawtimeDataobject into a numerical value (e.g., total minutes) depending on your needs.
内容的提问来源于stack exchange,提问作者Jens O. Anders Olsén

