VPick
A custom dropdown triggered by a button, with full keyboard navigation and group labels.
This page covers the parts every VPick has. Each of the bigger capabilities has its own page:
| Page | What it covers |
|---|---|
| Search | Type-ahead filtering, clearing, empty states |
| Multiselect | Multiple values, chips, select and deselect |
| Tree Select | Nested options, cascade selection, searching a tree |
| Slots | Replacing labels, icons, and the empty state |
| Positioning | Where the panel renders, scroll containers, inline mode |
| Forms | Labelling, submission, validation |
| Accessibility | Keyboard navigation, ARIA roles, screen readers |
| API | Every prop, slot, event, and method in one place |
Options
Accepts the same options shape as VPickNative. Flat arrays and grouped arrays both work, and groups are detected automatically when an item has an options array.
Grouped
Separators
Use separators to render a horizontal divider between adjacent groups.
Custom data shape
Use labelKey, valueKey, disabledKey, and groupOptionsKey to pass data straight from your API without mapping. See the Data Shape guide for the full reference.
labelKey also accepts an array, used as a fallback chain where the first key with a non-empty value wins. Useful when records are inconsistent:
<VPick :options="options" :label-key="['label', 'name']" value-key="id" />States
Disabled
Loading
Error
Appearance
Rotate icon
Rotates the chevron 180 degrees when the dropdown is open.
Scrollable
Long option lists scroll inside the dropdown. Max height is controlled by --vpick-listbox-max-height (default 16rem).
Sizing
By default, the trigger hugs its content (--vpick-width: fit-content) and the dropdown matches the trigger width at minimum. Give the trigger an explicit width and the dropdown will follow.
<VPick v-model="selected" :options="options" style="--vpick-width: 18rem" />Options wider than the trigger make the dropdown grow. To pin both widths identical and truncate long labels, also cap the listbox:
<VPick
v-model="selected"
:options="options"
style="
--vpick-width: 18rem;
--vpick-listbox-max-width: var(--vpick-trigger-width);
"
/>| Variable | Default | Effect |
|---|---|---|
--vpick-width | fit-content | Trigger width. |
--vpick-listbox-min-width | --vpick-trigger-width | Minimum dropdown width. |
--vpick-listbox-max-width | calc(100vw - 16px) | Maximum dropdown width. |
--vpick-listbox-max-height | 16rem | Maximum dropdown height before scrolling. |
--vpick-trigger-width is measured and set by Vue Pick on every open, so read it rather than assign it.
Object values
By default v-model holds plain values:
selected = ["apple", "banana"]Set valueFormat="object" and it holds your original option objects instead:
selected = [
{ id: "apple", label: "Apple", price: 3 },
{ id: "banana", label: "Banana", price: 2 },
]Useful when you need other fields off the selection and would otherwise look them up yourself. Both controls below hold the same selection:
<VPick
v-model="selected"
:options="fruit"
label-key="label"
value-key="id"
value-format="object"
/>Objects you pass back in are matched by valueKey, not by identity, so a rebuilt object literal still resolves:
selected = { id: "apple" } // matches the Apple optionThe hidden <select> used for form submission always posts plain values, since a form field cannot carry an object.
Core props
The props every VPick takes. The rest are listed on the page for the feature they belong to, and all of them together on the API Reference.
modelValueany default undefinedSelected value. Use v-model for two-way binding. In Vue 2 the prop is value.
placeholderstring default undefinedText shown when no value is selected.
disabledboolean default falseDisables the control.
loadingboolean default falseShows a spinner and disables interaction.
errorstring default undefinedError message. Applies error styling and aria-invalid.
idstring default undefinedHTML id, applied to the control itself so a <label for> resolves to it.
requiredboolean default falseHTML required attribute.
ariaLabelstring default undefinedaria-label, for when there is no visible label.
ariaDescribedbystring default undefinedaria-describedby, for wiring up hint or error text.
Data shape
labelKeystring | string[] default "label"Key to read each option's visible label from. An array acts as a fallback chain: the first key with a non-empty value wins.
childrenKeystring default "children"Key for nested children. Any option carrying that array turns tree mode on.
Appearance
separatorsboolean default falseDraws a divider between adjacent groups in the list.
rotateIconboolean default falseRotates the trigger chevron 180 degrees while open.
animateboolean default trueAnimates the multiselect chips. false adds and removes them outright.