Skip to main content
Vuetify0 v1.0 is here
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

createModel

Reactive value store that wraps a ref with two-way selection binding.

Edit this page
Report a Bug
Open issues
View on GitHub
Copy Markdown

StableIntermediateJul 19, 2026

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.

ts
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:

Model Hierarchy

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

Model Hierarchy

Options

OptionTypeDefaultNotes
disabledMaybeRefOrGetter<boolean>falseWhen truthy, all selection operations are silently skipped
enrollMaybeRefOrGetter<boolean>trueAuto-select tickets on registration; createSelection overrides this to false
multipleMaybeRefOrGetter<boolean>falseWhen 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/MethodReactiveNotes
selectedIdsshallowReactive(Set) — always reactive
selectedItemsComputed from selectedIds
selectedValuesComputed from selectedItems, unwraps refs via toValue
ticket isSelectedComputed 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
Tip

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

Examples

Compound Value

A model isn’t limited to one value. Register multiple tickets — each with its own ref and input type — and the model composes them into a single compound output. The compound output at the bottom is a toRef over selectedValues, so it updates whenever a ticket’s value changes or a ticket is toggled in or out of the composition.

Data Flow

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

Data Flow

Each ticket’s value can be any type: a string, a number, an array. The checkbox next to each ticket controls whether it’s included in the compound. Disabling a ticket freezes its value and prevents selection changes. Because each value is a ref, edits flow through the model reactively — type in the text field, pick a radio, check a topping, or drag the slider and the compound reflects the change immediately.

This pattern is the foundation for compound inputs like forms, filters, and configuration panels — anywhere multiple independent values need to be composed into a single reactive output.

FileRole
createCompound.tsCreates the model, registers four tickets with typed refs, exports reactive compound
compound.vueRenders each ticket with its matching input control, toggles composition membership
0 / 4 in compound
name
size
toppings
quantity
2
Compound Value
[]

Color Palette

This example uses createSelection (which extends createModel) to compose a palette from five OKLCH hue values. Each color is a ticket with a ref(hue) as its value — the hue sliders write directly to those refs, so dragging a slider shifts the color in real time without any re-registration.

Data Flow

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

Data Flow

The circle next to each color toggles it in or out of the composition. Purple is registered with disabled: true, so it can’t be toggled or adjusted. The composite strip at the bottom renders only the active colors as equal-width segments, with degree labels underneath.

The provider/consumer split keeps the model definition (model.ts) separate from the UI (ColorConsumer.vue). The provider creates the model and provides it via createContext; the consumer injects it and renders the controls. This is the same pattern you’d use in a real application to share model state across a component tree.

FileRole
model.tsCreates the selection, registers five OKLCH colors with ref(hue) values, exports context tuple
ColorProvider.vueCalls createColorModel() and provides context via slot
ColorConsumer.vueInjects context, renders hue sliders with gradient tracks and composite strip
colors.vueEntry point composing Provider around Consumer
Palette4 / 5
red
15°
blue
245°
green
155°
purple
290°
orange
55°
Composite
15° 245° 155° 55°
[
  15,
  245,
  155,
  55
]

FAQ

Discord
Need help? Join our community for support and discussions ↗

API Reference

The following API details are for the createModel composable.
Was this page helpful?

© 2016-1970 Vuetify, LLC
Services
Ctrl+/