createModel
Reactive value store that wraps a ref with two-way selection binding.
Usage
createModel stores a reactive value. Register a ref and useProxyModel keeps it synced — the same idea as defineModel but built on the registry pattern.
import { shallowRef } from 'vue'
import { createModel, useProxyModel } from '@vuetify/v0'
const value = shallowRef<string>()
const model = createModel()
model.register({ id: 'fruit', value })
// ticket is already selected — enroll defaults to true
useProxyModel(model, value)Tickets are enrolled on registration by default (enroll: true). With single-value semantics, only the most recently registered ticket is active. Pass enroll: false to opt out.
Most of the time you register a single ticket — that’s the only value you care about. The registry pattern underneath gives you the ability to compose multiple values into a compound model when you need it, which is what createSelection builds on.
Pass multiple: true to let select() accumulate IDs instead of clearing first. This is how createSlider keeps all thumbs selected simultaneously. Selection-specific concepts like mandatory belong in createSelection. Both composables accept enroll, but createSelection defaults it to false.
Architecture
createModel sits between createRegistry and the higher-level composables:
Options
| Option | Type | Default | Notes |
|---|---|---|---|
disabled | MaybeRefOrGetter<boolean> | false | When truthy, all selection operations are silently skipped |
enroll | MaybeRefOrGetter<boolean> | true | Auto-select tickets on registration; createSelection overrides this to false |
multiple | MaybeRefOrGetter<boolean> | false | When true, select() accumulates IDs without clearing first |
All three options accept a static value, a ref, or a getter — they are resolved with toValue() at call time.
Reactivity
Value state is always reactive. Collection methods follow the base createRegistry pattern.
| Property/Method | Reactive | Notes |
|---|---|---|
selectedIds | shallowReactive(Set) — always reactive | |
selectedItems | Computed from selectedIds | |
selectedValues | Computed from selectedItems, unwraps refs via toValue | |
ticket isSelected | Computed from selectedIds | |
apply(values, options?) | Sets selection from an array of values — used by useProxyModel to sync a ref with the model | |
selected(id) | — | Returns true if the given ID is currently selected |
reset() | — | Clears all selected IDs |
Value vs Collection Most UI patterns only need value reactivity (which is always on). You rarely need the collection itself to be reactive.
Examples
[]
[ 15, 245, 155, 55 ]
FAQ
createModel is a value store — register a ref and keep it synced with useProxyModel. Reach for createSelection when you need selection semantics like mandatory enforcement or ticket self-methods (select(), toggle()); createModel deliberately omits them.
createModel defaults enroll to true, since a two-way-bound value is expected to start active. Pass enroll: false to opt out. Note createSelection flips this default to false.
By default select() clears the previous selection first (single-value semantics). With multiple: true it accumulates IDs so several tickets stay active at once — this is how createSlider keeps every thumb selected simultaneously.
defineModel is a single component-level v-model. createModel stores values in a registry of tickets, so you can compose several values into one compound model and build selection on top — which is what createSelection does. Bridge a createModel value to a v-model ref with useProxyModel.