Vuetify Patterns
Quick Guide: Vuetify provides 80+ pre-styled Vue 3 components implementing Material Design. Configure withcreateVuetify()-- setthemefor colors,defaultsfor global component props, andblueprint: md3for MD3 compliance. Usev-defaults-providerfor scoped prop overrides. Customize at the SASS level with@use 'vuetify/settings'for compile-time changes. Current: v3.8.x --useRulescomposable for form validation, date picker improvements, performance optimizations. Vuetify is template-driven -- prefer declarative props/slots over imperative JS.
<critical_requirements>
CRITICAL: Before Using This Skill
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)
(You MUST install and register Vuetify as a Vue plugin via app.use(vuetify) -- components will not render without the plugin)
(You MUST use the defaults system in createVuetify() or v-defaults-provider for consistent component props -- never repeat the same prop on every instance)
(You MUST use named slots (v-slot:item.<key>, v-slot:prepend) for component customization -- not wrapper divs with manual styling)
(You MUST define v-data-table headers and column arrays outside the component -- inline arrays cause re-renders on every parent update)
</critical_requirements>
Auto-detection: Vuetify, vuetify, createVuetify, v-btn, v-card, v-data-table, v-text-field, v-select, v-autocomplete, v-dialog, v-navigation-drawer, v-app-bar, v-toolbar, v-chip, v-snackbar, v-form, v-defaults-provider, v-theme-provider, useTheme, useDisplay, useDate, useRules, mdi, @mdi/font, vuetify/blueprints, vuetify/settings, vuetify/styles
When to use:
- Building Vue 3 applications with pre-styled Material Design components
- Rapid development of admin dashboards, data tables, and CRUD interfaces
- Projects that benefit from a comprehensive defaults/theming system
- Applications requiring built-in accessibility, RTL, and i18n support
When NOT to use:
- Non-Vue projects (Vuetify is Vue-only)
- Projects requiring a non-Material Design aesthetic without heavy customization
- Minimal bundle size is critical and only a few components are needed (consider a headless library)
- Projects using Vue 2 (Vuetify 3 requires Vue 3)
Key patterns covered:
- Plugin setup with
createVuetify(), themes, and blueprints - Global defaults and scoped defaults with
v-defaults-provider - SASS variable customization at compile time
- Slot-based component customization
- Data tables with sorting, filtering, pagination, and custom column rendering
- Form validation with rules arrays and
useRulescomposable - Theme toggling and
useTheme/useDisplaycomposables
Detailed Resources:
- [examples/core.md](examples/core.md) -- Plugin setup, theming, defaults, SASS variables, blueprints, TypeScript, composables
- [examples/data-tables.md](examples/data-tables.md) -- v-data-table headers, slots, sorting, filtering, pagination, server-side
- [examples/forms.md](examples/forms.md) -- v-form, validation rules, useRules, input components, custom validation
- [examples/layout.md](examples/layout.md) -- v-app, v-app-bar, v-navigation-drawer, v-container/v-row/v-col grid, responsive patterns
- [reference.md](reference.md) -- Decision frameworks, component quick reference, anti-patterns
<philosophy>
Philosophy
Vuetify is an opinionated, batteries-included component library. Unlike headless libraries, Vuetify ships styled components with a complete design system. Its power comes from three layers of customization:
- Theme layer -- colors, dark mode, typography via
createVuetify({ theme }). All components inherit automatically. - Defaults layer -- global or scoped prop values via
defaultsconfig orv-defaults-provider. Change everyv-btntovariant="outlined"in one line. - SASS layer -- compile-time variable overrides via
@use 'vuetify/settings'. Changes border-radius, heights, font families at the CSS level.
Vuetify 3.x key features:
- Full Vue 3 Composition API support
- Tree-shakeable components via
vuetify-loader/vite-plugin-vuetify - Material Design 3 blueprint (
md3) for MD3 compliance - Built-in composables:
useTheme,useDisplay,useDate,useRules v-defaults-providerfor scoped prop cascading (unique to Vuetify)- Extensive slot system for deep component customization without CSS hacks
- Built-in i18n, RTL, and accessibility
</philosophy>
<patterns>
Core Patterns
Pattern 1: Plugin Setup
Every Vuetify app requires createVuetify() and app.use(). The plugin provides the theme, defaults, icons, and locale to all components.
import { createApp } from "vue";
import { createVuetify } from "vuetify";
const vuetify = createVuetify({
theme: {
defaultTheme: "light",
themes: {
light: {
colors: {
primary: "#1867C0",
secondary: "#5CBBF6",
},
},
},
},
defaults: {
VBtn: { variant: "flat", rounded: "lg" },
VTextField: { variant: "outlined", density: "comfortable" },
VCard: { elevation: 2, rounded: "lg" },
},
});
const app = createApp(App);
app.use(vuetify);
app.mount("#app");
Why good: single configuration point, all components inherit theme and default props, tree-shakeable
For blueprints, SASS variables, TypeScript augmentation, and SSR setup, see [examples/core.md](examples/core.md).
Pattern 2: Theming and Dark Mode
Define multiple themes in createVuetify and toggle with useTheme. Vuetify generates CSS variables for each theme.
<script setup>
import { useTheme } from "vuetify";
const theme = useTheme();
function toggleTheme() {
theme.global.name.value = theme.global.current.value.dark ? "light" : "dark";
}
</script>
<template>
<v-btn @click="toggleTheme" icon="mdi-brightness-6" />
</template>
Why good: reactive theme switching, CSS variables prevent flash of wrong theme, custom themes can extend built-in ones
For custom theme creation and color variations, see [examples/core.md](examples/core.md).
Pattern 3: Global Defaults and Scoped Defaults
The defaults system is Vuetify's most powerful consistency tool. Set props globally in createVuetify() or scope them with v-defaults-provider.
<template>
<!-- All buttons inside this provider get these defaults -->
<v-defaults-provider
:defaults="{
VBtn: { color: 'secondary', variant: 'tonal' },
VCard: { elevation: 0, border: true },
}"
>
<v-card>
<v-card-text>
<!-- This button is tonal + secondary without explicit props -->
<v-btn>Scoped Default</v-btn>
</v-card-text>
</v-card>
</v-defaults-provider>
</template>
Why good: eliminates prop repetition, section-specific styling without CSS, nests and cascades like CSS scoping
Pattern 4: Slot-Based Component Customization
Vuetify components expose named slots for every internal element. Use v-slot to replace or augment internal rendering.
<template>
<v-text-field label="Amount" type="number">
<template v-slot:prepend-inner>
<v-icon>mdi-currency-usd</v-icon>
</template>
<template v-slot:append-inner>
<v-chip size="x-small" color="success">.00</v-chip>
</template>
</v-text-field>
</template>
Why good: customizes internal elements without CSS overrides, type-safe slot props, preserves component behavior
For data table column slots, see [examples/data-tables.md](examples/data-tables.md).
Pattern 5: Data Table Overview
v-data-table handles sorting, pagination, filtering, and selection. Define headers outside the template, use v-slot:item.<key> for custom column rendering.
<script setup>
const headers = [
{ title: "Name", key: "name" },
{ title: "Status", key: "st