Skip to main content
You are viewing Pre-Alpha documentation.
Vuetify0 Logo
Theme
Mode
Accessibility
Vuetify
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

Composables

Composables are the foundation of v0. They provide headless logic that you can use directly or through wrapper components.


IntermediateFeb 18, 2026

Composables vs Components

Both approaches use the same underlying logic:

ts
// Direct composable usage
const selection = createSelection({ multiple: true })
selection.register({ id: 'a', value: 'Apple' })
selection.select('a')
vue
<template>
  <Selection.Root v-model="selected" multiple>
    <Selection.Item value="Apple">Apple</Selection.Item>
  </Selection.Root>
</template>

When to Use Each

Use Composables WhenUse Components When
Need full control over renderingWant declarative templates
Building custom abstractionsStandard UI patterns
Non-DOM contexts (stores, workers)Accessibility attrs needed
Maximum flexibilityFaster development
Tip

Components and composables are interchangeable. Every component uses a composable internally—you can always drop to the composable for more control.

Ask AI
How do I choose between composables and components for my use case?

Quick Reactivity Note

v0 uses minimal reactivity for performance. Unlike Vue’s default approach where everything is deeply reactive, v0 only makes reactive what must be reactive.

Selection state is always reactiveselectedId, selectedIds, and isSelected update your templates automatically. This covers 90% of use cases.

Registry collections are NOT reactive by default — methods like registry.values() return snapshots. If you need template updates when items change, wrap with useProxyRegistry():

ts
// ❌ Won't update template when items change
const items = registry.values()

// ✅ Reactive — template updates automatically
const proxy = useProxyRegistry(registry)
// Use proxy.values in your template
Tip

This is intentional! Most apps only need selection reactivity. For the full picture, see the Reactivity Guide.

Categories

Foundation

Factories that create other composables:

ComposablePurpose
createContextType-safe provide/inject
createTrinity[use, provide, context] tuple
createPluginVue plugin factory

Registration

Collection management primitives:

ComposablePurpose
createRegistryBase collection with lookup
createTokensDesign token aliases
createQueueTime-based queue
createTimelineUndo/redo history

Selection

State management for selection patterns:

ComposablePurpose
createSelectionMulti-select base
createSingleRadio, tabs, accordion
createGroupCheckboxes, tri-state
createStepWizard, stepper, carousel

Forms

Form state and validation:

ComposablePurpose
createFormValidation, dirty tracking

Reactivity

Reactive proxy utilities:

ComposablePurpose
useProxyModelv-model bridge
useProxyRegistryRegistry to reactive object

Plugins

App-level features installed via app.use():

ComposablePurpose
useThemeDark/light mode
useLocalei18n, RTL
useBreakpointsResponsive queries
useStoragePersistent state

Utilities

Standalone helpers:

ComposablePurpose
createFilterArray filtering
createPaginationPage navigation
createVirtualVirtual scrolling

Usage Patterns

Direct Factory Call

For standalone instances:

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

const tabs = createSelection({ multiple: false })
tabs.register({ id: 'home', value: 'Home' })
tabs.register({ id: 'about', value: 'About' })
tabs.select('home')

Context Injection

For component tree sharing:

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

const [useTabSelection, provideTabSelection] = createSelectionContext({
  namespace: 'tabs',
  multiple: false,
})
provideTabSelection()

// Child
const selection = useTabSelection()
selection.select('home')

Plugin Installation

For app-wide singletons:

main.ts
import { createApp } from 'vue'
import { createThemePlugin } from '@vuetify/v0'

const app = createApp(App)
app.use(
  createThemePlugin({
    default: 'light',
    themes: { light: {...}, dark: {...} },
  }),
)

Composing Composables

Build complex behavior by combining primitives:

composables/useDataTable.ts
import { createSelection, createFilter, createPagination } from '@vuetify/v0'

// Filterable, paginated selection
const items = ref([...])
const query = ref('')

const filter = createFilter()
const { items: filtered } = filter.apply(query, items)

const pagination = createPagination({
  size: () => filtered.value.length,
  itemsPerPage: 10,
})
const selection = createSelection({ multiple: true })

// Visible items with selection state
const visibleItems = computed(() => {
  const start = pagination.pageStart.value
  const end = pagination.pageStop.value
  return filtered.value.slice(start, end)
})

TypeScript

All composables are fully typed. The value type is inferred from registration:

ts
interface MyItem {
  id: string
  label: string
}

const selection = createSelection()
selection.register({ id: '1', value: { id: '1', label: 'First' } as MyItem })

// Type-safe access via ticket
const ticket = selection.get('1')
ticket?.value // MyItem
Ask AI
Which composables should I use for a data table with filtering and pagination?

Frequently Asked Questions

Was this page helpful?

© 2016-1970 Vuetify, LLC
Ctrl+/