createRegistry
Foundation for ordered, keyed collections. Items are registered with IDs and indexes, and can be looked up by ID, index, or value.
Usage
The createRegistry composable provides a powerful interface for managing collections of items in a registration-based system. It allows you to register, unregister, and look up items efficiently, while maintaining an index for quick access.
import { createRegistry } from '@vuetify/v0'
import type { RegistryTicket } from '@vuetify/v0'
interface Item extends RegistryTicket<string> {
label: string
}
const registry = createRegistry<Item>()
// Register individual items
const a = registry.register({ label: 'Alpha' })
const b = registry.register({ label: 'Beta' })
const c = registry.register({ label: 'Gamma' })
console.log(registry.size) // 3
console.log(a.index) // 0
// Look up by id
const found = registry.get(b.id)
console.log(found?.label) // 'Beta'
// Patch a field without replacing the ticket
registry.upsert(b.id, { label: 'Beta (updated)' })
// Move to a new position
registry.move(a.id, 2)
console.log(a.index) // 2
// Remove one
registry.unregister(c.id)
console.log(registry.size) // 2
// Bulk load
registry.onboard([
{ id: 'x', label: 'X' },
{ id: 'y', label: 'Y' },
])
// Bulk remove
registry.offboard(['x', 'y'])Context / DI
Use createRegistryContext to share a registry across a component tree:
import { createRegistryContext } from '@vuetify/v0'
export const [useItems, provideItems, items] =
createRegistryContext({ namespace: 'my:items' })
// In parent component
provideItems()
// In child component
const registry = useItems()
registry.register({ id: 'item-1', value: 'First' })Architecture
createRegistry is the foundation for specialized registration systems:
Each branch extends the base ticket pattern with domain-specific capabilities. See individual composable docs for their extension hierarchies.
Reactivity
createRegistry uses minimal reactivity by default for performance. Collection methods are not reactive unless you opt in.
| Method | Notes |
|---|---|
register(ticket) | Add a ticket to the registry |
unregister(id) | Remove a ticket by ID |
upsert(id, partial) | Register or update a ticket |
move(id, index) | Reorder a ticket to a new index position |
reorder(ids) | Reorder the registry to match a canonical permutation in one O(n) pass |
onboard(tickets) | Batch-register an array of tickets |
offboard(ids) | Batch-unregister an array of IDs |
batch(fn) | Run multiple mutations with a single cache invalidation and deferred events |
get(id) | Retrieve a ticket by ID |
has(id) | Check whether a ticket ID is registered |
browse(value) | Reverse-lookup — find ticket ID(s) by value |
lookup(index) | Find ticket ID by zero-based index |
seek(direction, from?, predicate?) | Find 'first' or 'last' ticket, optionally starting from an index and/or filtered by predicate |
keys() | All registered IDs as a readonly array |
values() | All registered tickets as a readonly array |
entries() | All [id, ticket] pairs as a readonly array |
clear() | Remove all tickets |
dispose() | Remove all tickets and clear event listeners |
Need reactive collections? Pass { reactive: true } to make keys(), values(), entries(), size, and per-ticket field reads reactive in templates and computeds. Upserts on existing tickets propagate through the shallowReactive wrapping. For event-driven snapshots — or when you want deep: true tracking or need reactivity without wrapping the tickets themselves — use useProxyRegistry with { events: true }.
Examples
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.