vuetify0
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseVuetify0 Skill
Vuetify0 开发技能
@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.
@vuetify/v0 — 适用于Vue 3的无头组合式函数与组件。无样式、专注逻辑的设计系统构建块。
如需详细的API签名和使用方法,请查看references/REFERENCE.md。
Installation
安装
bash
pnpm install @vuetify/v0No global plugin is required. Import only what you need:
ts
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'bash
pnpm install @vuetify/v0无需全局插件,按需导入即可:
ts
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
当你需要以下功能时,即可使用v0:
- 选择状态 — 单选、多选、分组或分步选择
- 无头UI — 符合WAI-ARIA标准的组件(标签页、对话框、复选框、单选框、弹出层)
- 表单验证 — 异步规则、字段级错误处理、提交处理
- 共享上下文 — 类型安全的provide/inject模式
- 集合管理 — 带生命周期事件的注册管理
- 浏览器工具 — SSR安全的环境检测、监听、事件处理
- 全局应用系统 — 主题配置、响应式断点、国际化、存储管理
Vuetify MCP
Vuetify MCP
For structured API access during development, add Vuetify MCP:
bash
claude mcp add --transport http vuetify-mcp https://mcp.vuetifyjs.com/mcpAvailable tools: , , , ,
get_vuetify0_skillget_vuetify0_composable_listget_vuetify0_composable_guideget_vuetify0_component_listget_vuetify0_component_guide开发过程中如需结构化API访问,请添加Vuetify MCP:
bash
claude mcp add --transport http vuetify-mcp https://mcp.vuetifyjs.com/mcp可用工具:, , , ,
get_vuetify0_skillget_vuetify0_composable_listget_vuetify0_composable_guideget_vuetify0_component_listget_vuetify0_component_guideDecision Tree
决策树
Before writing custom logic, check if v0 already provides it:
| Need | Use |
|---|---|
| Single item selection | |
| Multi-item selection | |
| Selection with "select all" | |
| Step wizard / carousel | |
| Tree / nested items | |
| Form validation | |
| Shared state (provide/inject) | |
| Collection tracking | |
| Overflow detection | |
| Stacking / z-index layers | |
| Filtering arrays | |
| Pagination | |
| Virtual scrolling | |
| Undo / redo | |
| Notification queue | |
| Design tokens | |
| Proxy model (v-model) | |
| Keyboard shortcuts | |
| Click outside | |
| Element resizing | |
| Element visibility | |
| Responsive breakpoints | |
| Theme switching | |
| Persistent storage | |
| SSR check | |
| Type guards | |
在编写自定义逻辑前,请先确认v0是否已提供对应功能:
| 需求 | 使用工具 |
|---|---|
| 单项选择 | |
| 多项选择 | |
| 带“全选”的选择 | |
| 分步向导/轮播 | |
| 树形/嵌套项 | |
| 表单验证 | |
| 共享状态(provide/inject) | |
| 集合跟踪 | |
| 溢出检测 | |
| 堆叠/z-index层级 | |
| 数组过滤 | |
| 分页 | |
| 虚拟滚动 | |
| 撤销/重做 | |
| 通知队列 | |
| 设计令牌 | |
| 代理模型(v-model) | |
| 键盘快捷键 | |
| 外部点击检测 | |
| 元素尺寸变化 | |
| 元素可见性 | |
| 响应式断点 | |
| 主题切换 | |
| 持久化存储 | |
| SSR检测 | |
| 类型守卫 | |
Headless Components
无头组件
All components are unstyled, accessible, and follow WAI-ARIA patterns. They use a compound sub-component pattern:
所有组件均为无样式、可访问性兼容,并遵循WAI-ARIA模式。采用复合子组件设计模式:
vue
<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>vue
<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>vue
<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>vue
<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 |
|---|---|
| Polymorphic element — render as any HTML tag |
| Image with fallback system |
| Checkbox with tri-state and group support |
| Modal with focus trap |
| Accordion (single or multi-expand) |
| Multi-selection container |
| Page navigation with First/Last/Next/Prev/Ellipsis |
| Toggle overlay (CSS anchor positioning) |
| Radio buttons with roving tabindex |
| Overlay backdrop |
| Generic selection container |
| Single-selection container |
| Stepper / wizard |
| Tab navigation with keyboard support |
Composables
组合式函数
Selection Patterns
选择模式
ts
// 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()ts
// 单项选择(如主题选择器、激活标签页)
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>
// 多项选择(如标签选择器、多选列表)
const selection = createSelection({ multiple: true })
selection.toggle('a')
selection.isSelected('a') // boolean
// 带“全选”的分组选择(如数据表格复选框)
const group = createGroup()
group.selectAll()
group.toggleAll()
group.isMixed // 部分选中时为true
// 顺序导航(如分步向导、轮播)
const stepper = createStep({ circular: true })
stepper.next()
stepper.prev()
stepper.first()
stepper.last()Forms
表单
ts
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
ts
const form = createForm()
form.register({
id: 'email',
value: '',
rules: [
v => !!v || '必填项',
v => /.+@.+/.test(v) || '邮箱格式无效',
async v => await checkAvailable(v) || '该邮箱已被占用'
]
})
form.submit() // 验证所有字段,返回 { valid, errors }文档:createForm
Context (Dependency Injection)
上下文(依赖注入)
ts
// 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'
})ts
// createContext — 类型安全的provide/inject
const [useTheme, provideTheme] = createContext<ThemeContext>('Theme')
// 提供者组件
provideTheme({ mode, toggle })
// 消费者组件(若未提供提供者,会抛出清晰的错误提示)
const { mode, toggle } = useTheme()
// createTrinity — 带默认值的上下文
const [useConfig, provideConfig, defaultConfig] = createTrinity<Config>('Config', {
theme: 'light',
locale: 'en'
})Data Utilities
数据工具
ts
// 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
ts
// 过滤
const { apply } = createFilter({ keys: ['name', 'email'] })
const filtered = apply(query, users)
// 分页
const pagination = createPagination({ page: 1, itemsPerPage: 10, length: 100 })
pagination.next()
// 虚拟滚动
const { virtualItems, totalHeight, scrollTo } = createVirtual({
items: largeList,
itemHeight: 48
})
// 撤销/重做
const timeline = createTimeline({ maxSize: 50 })
timeline.push(state)
timeline.undo()
// 带自动关闭的通知队列
const notifications = createQueue({ timeout: 5000 })
notifications.push({ message: '保存成功!' })Browser & DOM
浏览器与DOM
ts
// 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)')ts
// SSR安全的环境检测
import { IN_BROWSER, SUPPORTS_TOUCH, SUPPORTS_OBSERVER } from '@vuetify/v0/constants'
// DOM监听(组件卸载时自动清理)
const { width, height } = useResizeObserver(el)
const { isIntersecting } = useIntersectionObserver(el, { threshold: 0.1 })
// 事件监听
useEventListener(window, 'resize', onResize)
useHotkey('ctrl+k', openSearch)
useClickOutside(menuRef, close)
// 响应式
const { md, lgAndUp } = useBreakpoints()
const { matches } = useMediaQuery('(prefers-color-scheme: dark)')Plugins (App-Wide Systems)
插件(全局应用系统)
For features that need app-wide state, use plugins in :
main.tsts
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: , , , , , ,
createThemePlugincreateBreakpointsPlugincreateFeaturesPlugincreateLoggerPlugincreateLocalePlugincreateDatePlugincreateStoragePlugin如需全局状态管理功能,请在中使用插件:
main.tsts
import { createThemePlugin, createBreakpointsPlugin } from '@vuetify/v0'
app.use(
createThemePlugin({
themes: {
light: { colors: { primary: '#3b82f6' } },
dark: { colors: { primary: '#60a5fa' } },
}
})
)
app.use(createBreakpointsPlugin())
// 之后在任意组件中使用:
const { current, toggle } = useTheme()
const { md, lgAndUp } = useBreakpoints()可用插件:, , , , , ,
createThemePlugincreateBreakpointsPlugincreateFeaturesPlugincreateLoggerPlugincreateLocalePlugincreateDatePlugincreateStoragePluginAnti-Patterns
反模式
Don't write custom selection logic
避免编写自定义选择逻辑
ts
// 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)ts
// 不推荐 — v0已为你处理响应式、强制约束和事件
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)
}
// 推荐
const selection = createSelection({ multiple: true })
selection.toggle(id)Don't write custom provide/inject
避免编写自定义provide/inject
ts
// 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')ts
// 不推荐 — 无类型安全,提供者缺失时无错误提示
provide('theme', theme)
const theme = inject('theme') // 可能为undefined!
// 推荐 — 类型安全,提供者缺失时抛出明确错误
const [useTheme, provideTheme] = createContext<ThemeContext>('theme')Don't write manual SSR checks
避免手动编写SSR检测
ts
// Bad
if (typeof window !== 'undefined')
// Good
import { IN_BROWSER } from '@vuetify/v0/constants'
if (IN_BROWSER)ts
// 不推荐
if (typeof window !== 'undefined')
// 推荐
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基础层(无依赖)
├── createContext → 基础依赖注入
├── createPlugin → Vue插件工厂
└── createTrinity → [use, provide, default] 模式
注册管理层(基于基础层)
├── createRegistry → 集合管理
├── useProxyRegistry → 外部注册管理代理
└── useStack → 分层z-index管理
选择层(基于注册管理层)
├── createSelection → 多选(基础)
├── createSingle → 单选
├── createGroup → 多选+三态
├── createStep → 顺序导航
└── createNested → 层级选择
数据层(基于注册管理层)
├── createForm → 验证
├── createFilter → 数组过滤
├── createPagination → 分页导航
├── createVirtual → 虚拟滚动
├── createTokens → 设计令牌
├── createQueue → 带超时的FIFO队列
└── createTimeline → 撤销/重做
系统层(独立)
├── useResizeObserver → 元素尺寸监听
├── useIntersectionObserver → 可见性检测
├── useMutationObserver → DOM变化监听
├── useEventListener → 自动清理的事件监听
├── useHotkey → 键盘快捷键
├── useClickOutside → 外部点击检测
├── useToggleScope → 条件生效的作用域
└── createOverflow → 容器溢出检测
插件层(全局应用,基于createPlugin)
├── useTheme → 主题切换
├── useBreakpoints → 响应式断点检测
├── useLocale → 国际化
├── useDate → 日期工具
├── useStorage → localStorage/sessionStorage管理
├── useFeatures → 功能开关
├── usePermissions → 权限管理
├── useLogger → 日志管理
├── useHydration → SSR水合
└── useLazy → 延迟计算
转换工具
├── toArray → 标准化为数组
└── toReactive → MaybeRef转响应式Utility Functions
工具函数
ts
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 IDts
import { mergeDeep, clamp, range, debounce, useId } from '@vuetify/v0/utilities'
mergeDeep({}, defaults, overrides) // 深度合并(防原型污染)
clamp(value, 0, 100) // 数值范围限制
range(5) // [0, 1, 2, 3, 4]
range(5, 1) // [1, 2, 3, 4, 5]
const search = debounce(fn, 300) // 支持.clear()和.immediate()
const id = useId() // SSR安全的唯一IDType Guards
类型守卫
ts
import { isString, isNumber, isObject, isArray, isFunction, isBoolean, isNull, isUndefined, isNullOrUndefined, isPrimitive, isSymbol, isNaN } from '@vuetify/v0/utilities'ts
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/
- 文档: https://0.vuetifyjs.com
- 源码: https://github.com/vuetifyjs/0
- MCP: https://0.vuetifyjs.com/guide/tooling/vuetify-mcp
- AI工具: https://0.vuetifyjs.com/guide/tooling/ai-tools
- API参考: references/REFERENCE.md
- Discord社区: https://community.vuetifyjs.com/