VPick API
Every prop, slot, event, and method in one place. Each prop links to the page that explains it in context.
Props
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.
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.
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.
searchableboolean default falseSwaps the button trigger for an input with type-ahead filtering. No effect with multiple, which always uses that trigger.
filter(option, query) => boolean default undefinedReplaces the built-in matcher. Receives each option and the current query.
searchNestedboolean default falseIn tree mode, lets a multi-word query match across a node's ancestor path.
closeOnSelectboolean default see descriptionCloses the list after picking. Defaults to true in single-select and false in multiple; an explicit value applies to both.
searchKeysstring | string[] default undefinedExtra fields on your option objects to search, alongside the label.
fetchOptions(query: string, context: { signal?: AbortSignal }) => unknown[] | Promise<unknown[]> default undefinedAnswers what the user types with options, from a server or an in-browser search engine, instead of filtering options.
searchDebouncenumber default 300Milliseconds to wait after the last keystroke before calling fetchOptions. 0 asks on every keystroke.
searchingTextstring default "Searching..."Shown while fetchOptions is working on the typed query.
searchErrorTextstring default "Could not search. Click to retry"Shown when fetchOptions rejects. Clicking it asks again.
searchPromptTextstring default "Type to search"Shown with fetchOptions when nothing is typed and options is empty.
multipleboolean default falseAllows more than one selection. v-model becomes an array and the trigger draws chips.
backspaceRemovesboolean default trueBackspace on an empty search input removes the last chip.
sortValueBy"ORDER_SELECTED" | "LEVEL" | "INDEX" default "ORDER_SELECTED"Order of the emitted array and of the chips.
defaultExpandLevelnumber default undefinedLevels to pre-expand on open. 1 opens top-level branches, 2 opens two levels, and so on.
disableBranchNodesboolean default falseMakes branches unselectable, so only leaves can be picked. Clicking a branch row expands it instead.
cascadeboolean default trueIn multiple tree mode, selecting a branch selects its descendants. false gives independent nodes.
valueConsistsOf"LEAF_PRIORITY" | "ALL" | "BRANCH_PRIORITY" | "ALL_WITH_INDETERMINATE" default "LEAF_PRIORITY"Which nodes end up in v-model while cascade is active.
flattenSearchResultsboolean default falseDrops the ancestor rows and the indent from search results, leaving a flat list.
noChildrenTextstring default "No sub-options"Shown under an expanded branch whose children array is empty.
loadChildren(option: unknown) => Promise<unknown[]> default undefinedFetches a branch's children when it first opens. Mark those branches with children: null.
loadingChildrenTextstring default "Loading..."Shown under a branch while its children load.
loadChildrenErrorTextstring default "Could not load. Click to retry"Shown under a branch whose children failed to load. Clicking it retries.
teleportTostring | HTMLElement default auto-detectedWhere the panel is rendered. Naming a target skips auto-detection; <body> is the fallback.
strategy"auto" | "absolute" | "fixed" default "auto"How the panel is anchored once it is rendered.
hideWhenDetachedboolean default trueHides the panel while its trigger is scrolled out of view.
bodyLockboolean default see descriptionLocks scrolling while open. Unset, defaults to true in button mode and false in searchable mode.
alwaysOpenboolean default falseRenders the list inline in the page rather than as a dropdown. It cannot be closed.
valueFormat"id" | "object" default "id"Whether v-model holds plain values or your original option objects.
Slots
| Slot | Scope | Description |
|---|---|---|
icon | none | Custom chevron icon. Shown when not loading. |
loading | none | Custom loading indicator. Shown when loading is true. |
clear | none | Custom clear button content. Shown when clearable and a value is selected. |
empty | { query: string } | Custom empty state, for no options at all or a search that matches nothing. |
no-children | { option: OptionItem } | Custom content for an expanded branch whose children array is empty. Defaults to noChildrenText. |
no-children-icon | { option: OptionItem } | Icon for that same row, rendered on the column the leaf checkboxes use. |
value-label | { option: OptionItem } | Custom label for the selected value: the trigger label in single mode, each chip in multiple mode. |
option-label | { option: OptionItem, isBranch: boolean, isExpanded: boolean, depth: number } | Custom label for each row in the list. The chevron, checkbox and check icon stay put. |
Usage for each is on the Slots page.
Events
| Event | Payload | Description |
|---|---|---|
update:modelValue | any | Emitted when the selection changes. Vue 2 emits input, which is what v-model listens for there. |
search | string | Emitted on every keystroke in searchable mode. |
select | object | Emitted when an option is picked. Payload is your original option object. |
deselect | object | Emitted when an option is unpicked in multiple mode. Same payload as select. |
open | none | Emitted when the list opens. An alwaysOpen list starts open, so it does not emit this on mount. |
close | none | Emitted when the list closes, whether by Escape, an outside click, a pick, or becoming disabled. |
select and deselect hand back the exact object you passed in options. See when deselect fires for the two cases that are not obvious.
Methods
Reach these through a template ref.
| Method | Description |
|---|---|
focus() | Moves focus to the control. In searchable and multiple mode the list opens, the same as tabbing into it. |
<script setup>
import { ref } from "vue"
const pick = ref()
</script>
<template>
<VPick ref="pick" :options="options" />
<button @click="pick.focus()">Edit</button>
</template>CSS custom properties
Theming is documented separately, since the variables are shared with VPickNative. See Theming.
Types
interface OptionItem {
label: string
value: any
disabled?: boolean
// An array, even an empty one, marks this node as a branch.
children?: OptionItem[]
// Set by Vue Pick, not by you: the original object you passed in.
// Handed back by `select`/`deselect` and available in slots.
raw?: unknown
}
interface OptionGroup {
label: string
disabled?: boolean
options: OptionItem[]
}
type OptionOrGroup = OptionItem | OptionGroupSee the Data Shape guide for reading your own shapes without transforming them.