vuetify0
npx skills add https://github.com/vuetifyjs/0 --skill vuetify0
Agent 安装分布
Skill 文档
Vuetify0 Skill
@vuetify/v0 â Headless composables and components for Vue 3. Unstyled, logic-focused building blocks for design systems.
For detailed API signatures and usage, see references/REFERENCE.md.
Installation
pnpm install @vuetify/v0
No global plugin is required. Import only what you need:
import { createSelection } from '@vuetify/v0/composables'
import { Tabs } from '@vuetify/v0/components'
import { mergeDeep } from '@vuetify/v0/utilities'
import { IN_BROWSER } from '@vuetify/v0/constants'
import { Vuetify0DateAdapter } from '@vuetify/v0/date'
import type { ID } from '@vuetify/v0/types'
When to Use This Skill
Use v0 whenever you need:
- Selection state â single, multi, grouped, or stepped selection
- Headless UI â WAI-ARIA compliant components (tabs, dialogs, checkboxes, radios, popovers)
- Form validation â async rules, field-level errors, submit handling
- Shared context â type-safe provide/inject patterns
- Collection management â registries with lifecycle events
- Browser utilities â SSR-safe detection, observers, event handling
- App-wide systems â theming, breakpoints, locale, storage
Vuetify MCP
For structured API access during development, add Vuetify MCP:
claude mcp add --transport http vuetify-mcp https://mcp.vuetifyjs.com/mcp
Available tools: get_vuetify0_skill, get_vuetify0_composable_list, get_vuetify0_composable_guide, get_vuetify0_component_list, get_vuetify0_component_guide
Decision Tree
Before writing custom logic, check if v0 already provides it:
| Need | Use |
|---|---|
| Single item selection | createSingle |
| Multi-item selection | createSelection or createGroup |
| Selection with “select all” | createGroup (tri-state support) |
| Step wizard / carousel | createStep |
| Tree / nested items | createNested |
| Form validation | createForm |
| Shared state (provide/inject) | createContext or createTrinity |
| Collection tracking | createRegistry |
| Overflow detection | createOverflow |
| Stacking / z-index layers | useStack |
| Filtering arrays | createFilter |
| Pagination | createPagination |
| Virtual scrolling | createVirtual |
| Undo / redo | createTimeline |
| Notification queue | createQueue |
| Design tokens | createTokens |
| Proxy model (v-model) | useProxyModel |
| Keyboard shortcuts | useHotkey |
| Click outside | useClickOutside |
| Element resizing | useResizeObserver |
| Element visibility | useIntersectionObserver |
| Responsive breakpoints | useBreakpoints |
| Theme switching | useTheme |
| Persistent storage | useStorage |
| SSR check | IN_BROWSER |
| Type guards | isString, isNumber, isObject, etc. |
Headless Components
All components are unstyled, accessible, and follow WAI-ARIA patterns. They use a compound sub-component pattern:
Tabs
<script lang="ts" setup>
import { Tabs } from '@vuetify/v0/components'
</script>
<template>
<Tabs.Root v-model="active">
<Tabs.List>
<Tabs.Item value="overview">Overview</Tabs.Item>
<Tabs.Item value="features">Features</Tabs.Item>
</Tabs.List>
<Tabs.Panel value="overview">...</Tabs.Panel>
<Tabs.Panel value="features">...</Tabs.Panel>
</Tabs.Root>
</template>
Dialog
<script lang="ts" setup>
import { Dialog } from '@vuetify/v0/components'
</script>
<template>
<Dialog.Root v-model="open">
<Dialog.Activator>Open</Dialog.Activator>
<Dialog.Content>
<Dialog.Title>Confirm</Dialog.Title>
<Dialog.Description>Are you sure?</Dialog.Description>
<Dialog.Close>Cancel</Dialog.Close>
</Dialog.Content>
</Dialog.Root>
</template>
Available Components
| Component | Purpose |
|---|---|
Atom |
Polymorphic element â render as any HTML tag |
Avatar |
Image with fallback system |
Checkbox |
Checkbox with tri-state and group support |
Dialog |
Modal with focus trap |
ExpansionPanel |
Accordion (single or multi-expand) |
Group |
Multi-selection container |
Pagination |
Page navigation with First/Last/Next/Prev/Ellipsis |
Popover |
Toggle overlay (CSS anchor positioning) |
Radio |
Radio buttons with roving tabindex |
Scrim |
Overlay backdrop |
Selection |
Generic selection container |
Single |
Single-selection container |
Step |
Stepper / wizard |
Tabs |
Tab navigation with keyboard support |
Composables
Selection Patterns
// Single selection (e.g., theme picker, active tab)
const single = createSingle({ mandatory: 'force' })
single.register({ id: 'light', value: 'light' })
single.register({ id: 'dark', value: 'dark' })
single.select('dark')
single.selectedValue // Ref<string | undefined>
// Multi-selection (e.g., tag picker, multi-select list)
const selection = createSelection({ multiple: true })
selection.toggle('a')
selection.isSelected('a') // boolean
// Group with "select all" (e.g., data table checkboxes)
const group = createGroup()
group.selectAll()
group.toggleAll()
group.isMixed // true when partially selected
// Sequential navigation (e.g., stepper, carousel)
const stepper = createStep({ circular: true })
stepper.next()
stepper.prev()
stepper.first()
stepper.last()
Docs: createSingle | createSelection | createGroup | createStep | createNested
Forms
const form = createForm()
form.register({
id: 'email',
value: '',
rules: [
v => !!v || 'Required',
v => /.+@.+/.test(v) || 'Invalid email',
async v => await checkAvailable(v) || 'Email taken'
]
})
form.submit() // Validates all fields, returns { valid, errors }
Docs: createForm
Context (Dependency Injection)
// createContext â type-safe provide/inject
const [useTheme, provideTheme] = createContext<ThemeContext>('Theme')
// Provider component
provideTheme({ mode, toggle })
// Consumer component (throws helpful error if not provided)
const { mode, toggle } = useTheme()
// createTrinity â context with built-in defaults
const [useConfig, provideConfig, defaultConfig] = createTrinity<Config>('Config', {
theme: 'light',
locale: 'en'
})
Docs: createContext | createTrinity | createPlugin
Data Utilities
// Filtering
const { apply } = createFilter({ keys: ['name', 'email'] })
const filtered = apply(query, users)
// Pagination
const pagination = createPagination({ page: 1, itemsPerPage: 10, length: 100 })
pagination.next()
// Virtual scrolling
const { virtualItems, totalHeight, scrollTo } = createVirtual({
items: largeList,
itemHeight: 48
})
// Undo/redo
const timeline = createTimeline({ maxSize: 50 })
timeline.push(state)
timeline.undo()
// Notification queue with auto-dismiss
const notifications = createQueue({ timeout: 5000 })
notifications.push({ message: 'Saved!' })
Docs: createFilter | createPagination | createVirtual | createTimeline | createQueue | createOverflow
Browser & DOM
// SSR-safe environment checks
import { IN_BROWSER, SUPPORTS_TOUCH, SUPPORTS_OBSERVER } from '@vuetify/v0/constants'
// DOM observation (auto-cleanup on unmount)
const { width, height } = useResizeObserver(el)
const { isIntersecting } = useIntersectionObserver(el, { threshold: 0.1 })
// Events
useEventListener(window, 'resize', onResize)
useHotkey('ctrl+k', openSearch)
useClickOutside(menuRef, close)
// Responsive
const { md, lgAndUp } = useBreakpoints()
const { matches } = useMediaQuery('(prefers-color-scheme: dark)')
Docs: useResizeObserver | useIntersectionObserver | useMutationObserver | useEventListener | useHotkey | useClickOutside | useMediaQuery
Plugins (App-Wide Systems)
For features that need app-wide state, use plugins in main.ts:
import { createThemePlugin, createBreakpointsPlugin } from '@vuetify/v0'
app.use(
createThemePlugin({
themes: {
light: { colors: { primary: '#3b82f6' } },
dark: { colors: { primary: '#60a5fa' } },
}
})
)
app.use(createBreakpointsPlugin())
// Then in any component:
const { current, toggle } = useTheme()
const { md, lgAndUp } = useBreakpoints()
Available plugins: createThemePlugin, createBreakpointsPlugin, createFeaturesPlugin, createLoggerPlugin, createLocalePlugin, createDatePlugin, createStoragePlugin
Anti-Patterns
Don’t write custom selection logic
// Bad â v0 handles reactivity, mandatory constraints, and events for you
const selected = ref<string[]>([])
function toggle (id: string) {
const index = selected.value.indexOf(id)
if (index >= 0) selected.value.splice(index, 1)
else selected.value.push(id)
}
// Good
const selection = createSelection({ multiple: true })
selection.toggle(id)
Don’t write custom provide/inject
// Bad â no type safety, no error on missing provider
provide('theme', theme)
const theme = inject('theme') // Could be undefined!
// Good â type-safe, throws descriptive error if provider is missing
const [useTheme, provideTheme] = createContext<ThemeContext>('theme')
Don’t write manual SSR checks
// Bad
if (typeof window !== 'undefined')
// Good
import { IN_BROWSER } from '@vuetify/v0/constants'
if (IN_BROWSER)
Composition Hierarchy
Foundation (no dependencies)
âââ createContext â Basic DI
âââ createPlugin â Vue plugin factory
âââ createTrinity â [use, provide, default] pattern
Registry (uses Foundation)
âââ createRegistry â Collection management
âââ useProxyRegistry â External registry proxy
âââ useStack â Layered z-index management
Selection (uses Registry)
âââ createSelection â Multi-select (base)
âââ createSingle â Single-select
âââ createGroup â Multi + tri-state
âââ createStep â Sequential navigation
âââ createNested â Hierarchical
Data (uses Registry)
âââ createForm â Validation
âââ createFilter â Array filtering
âââ createPagination â Page navigation
âââ createVirtual â Virtual scrolling
âââ createTokens â Design tokens
âââ createQueue â FIFO with timeout
âââ createTimeline â Undo/redo
System (standalone)
âââ useResizeObserver â Element dimensions
âââ useIntersectionObserver â Visibility detection
âââ useMutationObserver â DOM mutations
âââ useEventListener â Auto-cleanup events
âââ useHotkey â Keyboard shortcuts
âââ useClickOutside â Outside click detection
âââ useToggleScope â Conditional effect scopes
âââ createOverflow â Container overflow detection
Plugins (app-wide, uses createPlugin)
âââ useTheme â Theme switching
âââ useBreakpoints â Responsive detection
âââ useLocale â i18n
âââ useDate â Date utilities
âââ useStorage â localStorage/sessionStorage
âââ useFeatures â Feature flags
âââ usePermissions â Permission management
âââ useLogger â Logging
âââ useHydration â SSR hydration
âââ useLazy â Deferred computation
Transformers
âââ toArray â Normalize to array
âââ toReactive â MaybeRef to reactive
Utility Functions
import { mergeDeep, clamp, range, debounce, useId } from '@vuetify/v0/utilities'
mergeDeep({}, defaults, overrides) // Deep merge (prototype-pollution safe)
clamp(value, 0, 100) // Clamp to range
range(5) // [0, 1, 2, 3, 4]
range(5, 1) // [1, 2, 3, 4, 5]
const search = debounce(fn, 300) // With .clear() and .immediate()
const id = useId() // SSR-safe unique ID
Type Guards
import { isString, isNumber, isObject, isArray, isFunction, isBoolean, isNull, isUndefined, isNullOrUndefined, isPrimitive, isSymbol, isNaN } from '@vuetify/v0/utilities'
Resources
- Docs: https://0.vuetifyjs.com
- Source: https://github.com/vuetifyjs/0
- MCP: https://0.vuetifyjs.com/guide/tooling/vuetify-mcp
- AI Tools: https://0.vuetifyjs.com/guide/tooling/ai-tools
- API Reference: references/REFERENCE.md
- Discord: https://community.vuetifyjs.com/