Skip to main content
Vuetify0 is now in alpha!
Vuetify0 Logo
Theme
Mode
Palettes
Accessibility
Vuetify One
Sign in to Vuetify One

Access premium tools across the Vuetify ecosystem — Bin, Play, Studio, and more.

Not a subscriber? See what's included

createSelection

A composable for managing the selection of items in a collection with automatic indexing and lifecycle management.


IntermediateApr 5, 2026

Usage

createSelection extends createModel with selection-specific concepts: mandatory enforcement, multiple selection mode, auto-enrollment, and ticket self-methods (select(), unselect(), toggle()). It is reactive and provides helper properties for working with selected IDs, values, and items.

ts
import { createSelection } from '@vuetify/v0'

const selection = createSelection()

selection.register({ id: 'apple', value: 'Apple' })
selection.register({ id: 'banana', value: 'Banana' })

selection.select('apple')
selection.select('banana')

console.log(selection.selectedIds) // Set(2) { 'apple', 'banana' }
console.log(selection.selectedValues.value) // Set(2) { 'Apple', 'Banana' }
console.log(selection.has('apple')) // true

Context / DI

Use createSelectionContext to share a selection instance across a component tree:

ts
import { createSelectionContext } from '@vuetify/v0'

export const [useTabs, provideTabs, tabs] =
  createSelectionContext({ namespace: 'my:tabs', multiple: false })

// In parent component
provideTabs()

// In child component
const selection = useTabs()
selection.select('tab-1')

Architecture

createSelection extends createModel with auto-enrollment and ticket self-methods:

Selection Hierarchy

Use controls to zoom and pan. Click outside or press Escape to close.

Selection Hierarchy

Options

OptionTypeDefaultNotes
mandatoryMaybeRefOrGetter<boolean>falsePrevent deselecting the last selected item
multipleMaybeRefOrGetter<boolean>falseAllow multiple IDs to be selected simultaneously
enrollMaybeRefOrGetter<boolean>falseAuto-select tickets on registration (note: createModel defaults to true)

Reactivity

Selection state is always reactive. Collection methods follow the base createRegistry pattern.

Property/MethodReactiveNotes
selectedIdsshallowReactive(Set) — always reactive
selectedItemsComputed from selectedIds
selectedValuesComputed from selectedItems
ticket isSelectedComputed from selectedIds
apply(values, options?)Sync selection from external values — resolves values to IDs via browse(), then adds/removes to match
Tip

Reactive options The mandatory, multiple, and enroll options all accept MaybeRefOrGetter<boolean>. Pass a getter to drive selection behavior from a prop or computed:

ts
const props = defineProps<{ multiple?: boolean }>()
const selection = createSelection({ multiple: () => props.multiple ?? false })
Tip

Selection vs Collection Most UI patterns only need selection reactivity (which is always on). You rarely need the collection itself to be reactive.

Examples

Bookmark Manager

Multi-component bookmark manager using provide/inject. The provider creates and shares the selection context; consumers read and toggle selections independently.

FileRole
bookmark-manager.vueEntry point composing provider and consumers
context.tsCreates and types the bookmark selection context
BookmarkProvider.vueProvides the selection context and renders item list
BookmarkConsumer.vueConsumes context to display and toggle selections

File Picker

Multi-selectable file list with disabled states, demonstrating mandatory, select(), unselect(), and the isSelected ticket property.

0 selected

Selected: nothing

API Reference

The following API details are for the createSelection composable.

Functions

createSelection

(_options?: SelectionOptions) => R

Creates a new selection instance for managing multiple selected items. Extends `createModel` with multi-select, mandatory enforcement, auto-enrollment, and ticket self-methods. Supports disabled items, mandatory selection enforcement, and auto-enrollment.

createSelectionContext

(_options?: SelectionContextOptions) => ContextTrinity<R>

Creates a new selection context.

useSelection

(namespace?: string) => R

Returns the current selection instance.

Options

events

boolean | undefined

Enable event emission for registry operations

Default: false

reactive

boolean | undefined

Enable reactive behavior for registry operations

Default: false

disabled

MaybeRefOrGetter<boolean> | undefined

Disabled state for the entire model instance

Default: false

enroll

MaybeRefOrGetter<boolean> | undefined

Auto-select tickets on registration

Default: true

multiple

MaybeRefOrGetter<boolean> | undefined

Allow multiple tickets to be selected simultaneously

Default: false

mandatory

MaybeRefOrGetter<boolean | "force"> | undefined

Controls mandatory selection behavior: - `false` (default): No mandatory selection enforcement - `true`: Prevents deselecting the last selected item - `'force'`: Automatically selects the first non-disabled item on registration

Properties

collection

ReadonlyMap<ID, E>

The collection of tickets in the registry

size

number

The number of tickets in the registry

selectedIds

Reactive<Set<ID>>

Set of currently selected ticket IDs

selectedItems

ComputedRef<Set<E>>

Computed Set of selected ticket instances

selectedValues

ComputedRef<Set<E["value"] extends Ref<infer U, infer U> ? U : E["value"]>>

Computed Set of selected ticket values

disabled

MaybeRefOrGetter<boolean>

Disabled state for the entire model instance

multiple

MaybeRefOrGetter<boolean>

Whether the selection allows multiple selections

Methods

clear

() => void

Clear the entire registry

has

(id: ID) => boolean

Check if a ticket exists by ID

keys

() => readonly ID[]

Get all registered IDs

browse

(value: E["value"]) => ID[] | undefined

Browse for an ID(s) by value

lookup

(index: number) => ID | undefined

lookup a ticket by index number

get

(id: ID) => E | undefined

Get a ticket by ID

upsert

(id: ID, ticket?: Partial<Z>, event?: string) => E

Update or insert a ticket by ID

values

() => readonly E[]

Get all values of registered tickets

entries

() => readonly [ID, E][]

Get all entries of registered tickets

unregister

(id: ID) => void

Unregister a ticket by ID

reindex

() => void

Reset the index directory and update all tickets

move

(id: ID, toIndex: number) => E | undefined

Seek for a ticket based on direction and optional predicate

seek

(direction?: "first" | "last", from?: number, predicate?: (ticket) => boolean) => E | undefined

on

<K extends Extensible<RegistryEventName>>(event: K, cb: EventHandler<E, K>) => void

Listen for registry events

off

<K extends Extensible<RegistryEventName>>(event: K, cb: EventHandler<E, K>) => void

Stop listening for registry events

emit

<K extends Extensible<RegistryEventName>>(event: K, data: EventPayload<E, K>) => void

Emit an event with data

dispose

() => void

Clears the registry and removes all listeners

onboard

(registrations: Partial<Z & RegistryTicket>[]) => E[]

Onboard multiple tickets at once

offboard

(ids: ID[]) => void

Offboard multiple tickets at once

batch

<R>(fn: () => R) => R

Execute operations in a batch, deferring cache invalidation and event emission until complete

reset

() => void

Reset selection state without destroying the registry

select

(id: ID) => void

Select a ticket by ID

unselect

(id: ID) => void

Unselect a ticket by ID

toggle

(id: ID) => void

Toggle a ticket's selection state

selected

(id: ID) => boolean

Check if a ticket is currently selected

apply

(values: unknown[], options?: { multiple?) => void

Apply external values to the model

register

(ticket?: Partial<Z>) => E

Register a new ticket (accepts input type, returns output type)

mandate

() => void

Mandate selected ID based on "mandatory" option

Benchmarks

Every operation is profiled across multiple dataset sizes to measure real-world throughput. Each benchmark is assigned a performance tier—good, fast, blazing, or slow—and groups are scored by averaging their individual results so you can spot bottlenecks at a glance. This transparency helps you make informed decisions about which patterns scale for your use case. Learn more in the benchmarks guide.

View benchmark source↗

Was this page helpful?

© 2016-1970 Vuetify, LLC
Ctrl+/