# Date Picker

WARNING

v2.0.0 has introduced a significant number of breaking changes.

Read the upgrade guide for details.

v-date-picker is a feature-rich date picker implemented as a wrapper for v-calendar. That means that, out of the box, it accepts all props and emits all of the same events.

# Single Dates

v-date-picker can bind to single dates using the v-model directive.

September 2023
S
M
T
W
T
F
S
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
<v-date-picker v-model="date" />
data() {
  return {
    date: new Date(),
  }
}

# Date Ranges

Binding to date ranges is also supported by setting the is-range prop.

January 2020
S
M
T
W
T
F
S
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
<v-date-picker v-model="range" is-range />
data() {
  return {
    range: {
      start: new Date(2020, 0, 1),
      end: new Date(2020, 0, 5)
    }
  }
}

# Selection Modes 🎉

Introduced in v2.0.0

Use the mode prop to switch between 3 different date selection modes: date, dateTime and time.

WARNING

Previous to v2.0.0, the mode prop was used to switch between date, range and multiple date selections. As of v2.0.0, the mode prop has been repurposed for the date and time options. To get the previous range mode behavior, use the new is-range prop. To get the previous multiple mode behavior, here is an example of how to do that.

# Date

To limit user selection to only date components (month, day, year), use mode: 'date'. This is the default prop value, so it isn't explicitly required.

September 2023
S
M
T
W
T
F
S
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
Date (ISO): 2023-09-07T20:13:59.712Z
<v-date-picker mode="date" v-model="date" />

# Date & Time

To allow user selection of date and time components, use mode: 'dateTime'. A time picker now appears below the calendar.

TIP

Time components are set using the current timezone setting set by the timezone prop. By default, this value is null, which specifies the local timezone.

September 2023
S
M
T
W
T
F
S
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
Date (ISO): 2023-09-07T20:13:59.757Z
<div>
  <div class="flex mb-2">
    <label class="text-gray-600 font-medium"><input class="mr-1" type="radio" value="" v-model="timezone">Local</label>
    <label class="text-gray-600 font-medium ml-3"><input class="mr-1" type="radio" value="utc" v-model="timezone">UTC</label>
  </div>
  <v-date-picker v-model="date" mode="dateTime" :timezone="timezone" />
</div>
data() {
  return {
    date: new Date(),
    timezone: '',
  }
}

# 24-hr Mode

Use the is24hr prop to adjust the hour select element and default input format for 24-hr mode.

<v-date-picker v-model="date" mode="dateTime" is24hr>
  <template v-slot="{ inputValue, inputEvents }">
    <input
      class="px-2 py-1 border rounded focus:outline-none focus:border-blue-300"
      :value="inputValue"
      v-on="inputEvents"
    />
  </template>
</v-date-picker>
export default {
  data() {
    return {
      date: new Date(),
    };
  },
};

# Valid Hours

Use the valid-hours prop to provide an array of valid hours, an object with min and/or max hours, or a validation function. It works best for pickers in 24-hour mode, but also works with 12-hour mode.

September 2023
S
M
T
W
T
F
S
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
<!-- Array of valid hours -->
<v-date-picker v-model="date" :valid-hours="[0,3,4,5,8,16,20]" is24hr />
September 2023
S
M
T
W
T
F
S
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
<!-- Object with min/max hours -->
<v-date-picker v-model="date" :valid-hours="{ min: 4, max: 17 }" is24hr />
September 2023
S
M
T
W
T
F
S
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
<!-- 8-12AM only on weekends -->
<v-date-picker v-model="date" :valid-hours="(hour, { weekday }) => ![1, 7].includes(weekday) || (hour >= 8 && hour <= 12)" />

# Minute Increments

Use the minute-increment prop to set custom intervals for the minute select options.

September 2023
S
M
T
W
T
F
S
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
<v-date-picker v-model="date" mode="dateTime" :minute-increment="5" />
export default {
  data() {
    let date = new Date();
    date.setMinutes(0, 0, 0);
    return {
      date,
    };
  },
};

WARNING

Previous to v2.4.0, if the bound date does not match of the the minute options derived by the minute-increment amount, the accurate minute amount will be displayed, but this option will be disabled.

For v2.4.0 and after, times are rounded to the nearest available minute and hour.

# Time

To limit user selection to only time components (hours, minutes, seconds), use mode: 'time'.

Date (ISO): 2023-09-07T20:14:14.488Z
<div>
  <div class="flex mb-2" v-if="mode !== 'date'">
    <label class="text-gray-600 font-medium"><input class="mr-1" type="radio" value="" v-model="timezone">Local</label>
    <label class="text-gray-600 font-medium ml-3"><input class="mr-1" type="radio" value="utc" v-model="timezone">UTC</label>
  </div>
  <v-date-picker mode="time" v-model="date" :timezone="timezone" />
  <div class="flex items-baseline mt-2">
    <span class="text-gray-600 font-semibold tracking-wide">Date (ISO):</span>
    <span class="text-gray-800 ml-2">{{ date.toISOString() }}</span>
  </div>
</div>
export default {
  data() {
    return {
      date: new Date(),
      timezone: '',
    };
  },
}

# Model Config 🎉

Introduced in v2.0.0

The model-config prop is used to provide information about the date bound to v-date-picker. For example, if the date you provide is stored in a database as a string, this string value can be bound to v-date-picker directly, without any extra conversion logic required by your application.

In short, the model-config and timezone props help provide a no-hassle approach to working with your data.

# Strings

To bind to a string value, provide a model-config with the necessary type: 'string' and mask properties.

January 1983
S
M
T
W
T
F
S
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5

Customer Info

Name:Nathan Reyes
Birthday:1983-01-21
<v-date-picker
  v-model="customer.birthday"
  :model-config="modelConfig"
  is-required
  />
export default {
  data() {
    return {
      customer: {
        name: 'Nathan Reyes',
        birthday: '1983-01-21',
      },
      modelConfig: {
        type: 'string',
        mask: 'YYYY-MM-DD', // Uses 'iso' if missing
      },
    }
  }
};

# Numbers

To bind to a number value, provide a model-config with the necessary type: 'number' property.

January 1983
S
M
T
W
T
F
S
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5

Customer Info

Name:Nathan Reyes
Birthday:411976800000
<v-date-picker v-model="customer.birthday" :model-config="modelConfig" />
export default {
  data() {
    return {
      customer: {
        name: 'Nathan Reyes',
        birthday: 411976800000, // Milliseconds since 1 January 1970 
      },
      modelConfig: {
        type: 'number',
      },
    }
  }
};

# Time Adjust

By default, when the user selects a new date, it leaves the existing time value. To auto-adjust the time for selected dates, provide a model-config with the desired timeAdjust setting in HH:mm:ss format. All times use the specified timezone, or local timezone if none is provided.

This example assigns the time of selected dates to noon in the browser's local timezone.

January 1983
S
M
T
W
T
F
S
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5

Customer Info

Name:Nathan Reyes
Birthday:1983-01-21T07:30:00.000Z
<v-date-picker v-model="date" :model-config="modelConfig">
data() {
  return {
    customer: {
      name: 'Nathan Reyes',
      birthday: '1983-01-21T07:30:00.000Z',
    },
    modelConfig: {
      type: 'string',
      mask: 'iso',
      timeAdjust: '12:00:00',
    },
  }
}
Time Setting Description
HH:mm:ss Custom time in HH:mm:ss format
now Assign to the instant of date selection.

# Adjust Date Range Times

When used with date ranges, the modelConfig may be specified as an object with start and end properties. For example, when the users selects a date range, we might want to set the selected range to start at the very beginning of the first day until the end of the last day.

January 2020
S
M
T
W
T
F
S
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8

Select Date Range

Start:Mon Jan 06 2020 00:00:00 GMT+0000 (Coordinated Universal Time)
End:Thu Jan 09 2020 00:00:00 GMT+0000 (Coordinated Universal Time)
<v-date-picker v-model="range" :model-config="modelConfig" is-range >
data() {
  return {
    range: {
      start: new Date(2020, 0, 6),
      end: new Date(2020, 0, 9),
    },
    modelConfig: {
      start: {
        timeAdjust: '00:00:00',
      },
      end: {
        timeAdjust: '23:59:59',
      },
    },
  }
}

# Popovers

To display the picker as a popover, provide your own content as the default slot. Most often this will be an input element.

WARNING

As of v2.0.0, v-date-picker no longer provides an input element as the default slot. This slot must be provided by the developer. Additionally, the inputProps prop as been deprecated in favor of simply binding the input value to the inputValue slot prop.

# Input

To allow for user date text entry, provide a custom input element as the default slot. v-date-picker provides formatting, parsing and event handling out of the box via the following slot props:

  • inputValue: The is the value you should bind to your input. This value will update as new dates are assigned and validated by the component.
  • inputEvents: These events include handlers for events that ultimately assign new dates and manage the appearance of the popover (as specified via the popover prop).
<v-date-picker v-model="date">
  <template v-slot="{ inputValue, inputEvents }">
    <input
      class="bg-white border px-2 py-1 rounded"
      :value="inputValue"
      v-on="inputEvents"
    />
  </template>
</v-date-picker>
export default {
  data() {
    return {
      date: new Date(),
    };
  },
};

# Range Inputs

When binding to a date range and providing custom input elements, the inputValue and inputEvents are split into separate start and end sub-properties.

<v-date-picker v-model="range" is-range>
  <template v-slot="{ inputValue, inputEvents }">
    <div class="flex justify-center items-center">
      <input
        :value="inputValue.start"
        v-on="inputEvents.start"
        class="border px-2 py-1 w-32 rounded focus:outline-none focus:border-indigo-300"
      />
      <svg
        class="w-4 h-4 mx-2"
        fill="none"
        viewBox="0 0 24 24"
        stroke="currentColor"
      >
        <path
          stroke-linecap="round"
          stroke-linejoin="round"
          stroke-width="2"
          d="M14 5l7 7m0 0l-7 7m7-7H3"
        />
      </svg>
      <input
        :value="inputValue.end"
        v-on="inputEvents.end"
        class="border px-2 py-1 w-32 rounded focus:outline-none focus:border-indigo-300"
      />
    </div>
  </template>
</v-date-picker>
export default {
  data() {
    return {
      range: {
        start: new Date(2020, 9, 12),
        end: new Date(2020, 9, 16),
      },
    };
  },
};

# Debounce

Use the input-debounce prop (in milliseconds) to set a custom debounce duration. This example makes the input a little more responsive to text input by using a debounce of 500ms rather than the default 1000ms.

<v-date-picker v-model="date" :input-debounce="500">
  <template v-slot="{ inputValue, inputEvents }">
    <input
      class="bg-white border px-2 py-1 rounded"
      :value="inputValue"
      v-on="inputEvents"
    />
  </template>
</v-date-picker>
export default {
  data() {
    return {
      date: new Date(),
    };
  },
};

# Disable Update On Input

To completely disable value updates as the user types, set the update-on-input prop to false. This will defer updates until the input's change event occurs.

<v-date-picker v-model="date" :update-on-input="false">
  <template v-slot="{ inputValue, inputEvents }">
    <input
      class="bg-white border px-2 py-1 rounded"
      :value="inputValue"
      v-on="inputEvents"
    />
  </template>
</v-date-picker>
export default {
  data() {
    return {
      date: new Date(),
    };
  },
};

# Format & Parse

By default, the localized format will be used to format and parse the input text.

Just like the v-calendar component, v-date-picker accepts an explicit locale prop. This might be preferred if you store your user's locale in a database or want to force all user's to a specific locale.

<v-date-picker v-model="date" :locale="locale">
  <template v-slot="{ inputValue, inputEvents }">
    <input
      class="bg-white border px-2 py-1 rounded"
      :value="inputValue"
      v-on="inputEvents"
    />
  </template>
</v-date-picker>
data() {
  return {
    date: new Date(),
    locale: null,
  };
},
created() {
  // Fetch user's locale using custom API (eg. 'en-ZA')
  this.locale = await api.getUserLocale();
}

To use a custom mask that overrides the locale, assign the masks.input prop.

<v-date-picker v-model="date" :masks="masks">
  <template v-slot="{ inputValue, inputEvents }">
    <input
      class="bg-white border px-2 py-1 rounded"
      :value="inputValue"
      v-on="inputEvents"
    />
  </template>
</v-date-picker>
data() {
  return {
    date: new Date(),
    masks: {
      input: 'YYYY-MM-DD',
    },
  };
},

Please reference the formatting & parsing section for a complete list of available mask tokens.

# Form Example

Here is a more complex example using a custom input with a validation message and Clear button to clear out the date.

Date is required.

<div class="w-full max-w-sm">
  <form class="bg-white shadow-md rounded px-8 pt-6 pb-8" @submit.prevent>
    <label class="block text-gray-600 text-sm font-bold mb-2" for="date"
      >Select Date</label
    >
    <div class="flex w-full">
      <v-date-picker v-model="date" class="flex-grow">
        <template v-slot="{ inputValue, inputEvents }">
          <input
            id="date"
            class="bg-white text-gray-700 w-full py-2 px-3 appearance-none border rounded-l focus:outline-none"
            :class="{ 'border-red-600': errorMessage }"
            :value="inputValue"
            v-on="inputEvents"
          />
        </template>
      </v-date-picker>
      <button
        type="button"
        class="text-white font-bold py-2 px-4 rounded-r user-select-none focus:outline-none"
        :class="date ? 'bg-red-500' : 'bg-red-300'"
        :disabled="!date"
        @click="date = null"
      >
        Clear
      </button>
    </div>
    <p class="text-red-600 text-xs italic mt-1" v-if="errorMessage">
      {{ errorMessage }}
    </p>
    <p class="text-blue-500 text-xs font-bold mt-1" v-else>
      We got it. Thanks!
    </p>
  </form>
</div>
export default {
  data() {
    return {
      date: null,
    };
  },
  computed: {
    errorMessage() {
      if (!this.date) return 'Date is required.';
      return '';
    },
  },
};

# Advanced Slots

Besides inputs, other elements may be effectively used as the default slot. When doing so, there are other slot variables that you may use to further customize date selection behavior.

TIP

See the date picker examples for more guidance on using these slot variables.

Here is a comprehensive list of the available slot props.

Prop Type Description
inputValue Object Input text value.
inputEvents Object Events that are configured based on the props provided to v-date-picker, including input, change and keyup. Props like update-on-input and input-debounce are handled appropriately.
isDragging Boolean Set when the user is dragging a new range selection.
updateValue Function Call to update the value at the time of your choosing.
showPopover Function Call to manually show the popover.
hidePopover Function Call to manually hide the popover.
togglePopover Function Call to show/hide the popover.
getPopoverTriggerEvents Function Call to get the bindable events for a given display mode.

# updateValue()

Call updateValue(value, opts) to manually update the date value with some side-effect options. All side-effects assume that the provided value is valid.

TIP

Values passed to updateValue() are validated against disabled-dates, available-dates, min-date and max-date props.

Parameter Type Description Default Value
value Date, String, Number New date value undefined
opts.formatInput Boolean Reformat the inputValue. true
opts.hidePopover Boolean Hide the popover. false
opts.debounce Number Debounce rate (ms) for which the value is assigned. undefined
opts.adjustPageRange Boolean Adjust the from-page in order to properly display the value. undefined

# Disable Dates

Refer to the disabling dates section.

# Require Selected Date

Setting the is-required prop will prevent clearing the date value by deleting all text from the input element or re-selecting a picker date.

<v-date-picker v-model="date" is-required>
  <template v-slot="{ inputValue, inputEvents }">
    <input
      class="bg-white border px-2 py-1 rounded"
      :value="inputValue"
      v-on="inputEvents"
    />
  </template>
</v-date-picker>
export default {
  data() {
    return {
      date: new Date(),
    };
  },
};

# Customize Attributes

v-date-picker uses the following props to display date selections:

Attribute Description
select-attribute Attribute used to represent the selected value.
drag-attribute Attribute used to represent the dragged value. Valid only when mode === "range".

To customize these attributes, we just need to provide our own custom attributes objects. Any attributes we provide will replace the default ones.

TIP

Both attributes are assigned a key of "select-drag".

For example, say we want to use a dot instead of a highlight to denote the selected date. All we would need to do is pass a new select-attribute:

September 2023
S
M
T
W
T
F
S
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
<v-date-picker
  v-model="date"
  :select-attribute="selectAttribute"
/>
export default {
  data() {
    return {
      date: new Date(),
      selectAttribute: {
        dot: true,
      },
    };
  },
};

# Selection Popover

Finally, let's look at an example of adding a simple popover to the dragged and selected date ranges. Note that here we include the day-popover slot, and make sure to assign a truthy value to the popover property of the attribute.

We'll first try to display the dragged range, then fall back to the selected range.

January 2018
S
M
T
W
T
F
S
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
<v-date-picker
  v-model="range"
  :select-attribute="selectDragAttribute"
  :drag-attribute="selectDragAttribute"
  is-range
  @drag="dragValue = $event"
>
  <template v-slot:day-popover="{ format }">
    <div>
      {{ format(dragValue ? dragValue.start : range.start, 'MMM D') }}
      -
      {{ format(dragValue ? dragValue.end : range.end, 'MMM D') }}
    </div>
  </template>
</v-date-picker>
export default {
  data() {
    return {
      dragValue: null,
      range: {
        start: new Date(2018, 0, 8),
        end: new Date(2018, 0, 12),
      },
    };
  },
  computed: {
    selectDragAttribute() {
      return {
        popover: {
          visibility: 'hover',
          isInteractive: false, // Defaults to true when using slot
        },
      };
    },
  },
};