关于 web-ui-vuetify
web-ui-vuetify 是面向 Vue 3 开发者的 Vuetify 实践指南,介绍组件配置、主题和默认属性等定制层,以及布局、表格、表单和响应式模式。
主要功能
- 01Vuetify 插件与主题配置
- 02主题、默认值和 SASS 定制
- 03使用插槽自定义组件
- 04数据表格选择与配置
- 05表单规则与验证
- 06响应式布局与显示逻辑
适用场景
- 01为 Vue 3 应用配置 Vuetify
- 02调整主题、暗色模式和组件默认值
- 03构建数据表格和表单验证
- 04根据屏幕尺寸调整组件呈现
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ agents-inc/ skills --skill web-ui-vuetify安装后在 Claude Code 中输入/web-ui-vuetify确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
metadata.yamlreference.mdexamples/core.mddata-tables.mdforms.mdlayout.md详细介绍
Vuetify 模式
快速指南: Vuetify 提供八十多个预先设置样式的 Vue 3 组件,用于实现 Material Design,并通过一次
createVuetify()调用进行配置。首先要了解的是,它有三个自定义层——主题、默认值和 SASS,三者不可互换。应通过负责相应属性的层进行自定义;如果需要使用 CSS 覆盖,通常说明选错了层。Vuetify 全面采用模板驱动的方式——具名插槽可替换内部标记,因此通常不需要添加包装用的div。当前主版本:v3.x,提供用于验证的useRules和用于限定作用域的属性级联的v-defaults-provider。
详细资源:
- examples/core.md — 插件设置、主题、默认值、SASS、蓝图、图标、SSR
- examples/data-tables.md — 表头、列插槽、服务端、虚拟滚动、分组
- examples/forms.md —
v-form、规则、useRules、输入组件 - examples/layout.md —
v-app、应用栏、抽屉、网格、对话框、提示条 - reference.md — 组件表、断点、密度和变体取值、反模式
适用路径
是否安装构建插件,会影响你需要在两个文件中编写的内容。
- 使用
vite-plugin-vuetify或webpack-plugin-vuetify时。 组件会自动解析并进行摇树优化,因此无需手动导入任何内容,也完全不需要导入"vuetify/styles"。只有此路径支持通过styles.configFile覆盖 SASS 变量。请参阅 examples/core.md。 - 未使用时。 导入
vuetify/components和vuetify/directives并进行注册,同时在入口文件中导入"vuetify/styles"。所有内容都会打包,因此构建包会包含每个组件。
<critical_requirements>
编写 Vuetify 代码之前
使用 app.use(vuetify) 注册插件。 每个组件都会通过它解析,因此如果没有注册,Vue 会将 <v-btn> 视为未知元素,并渲染为空的自定义标签,而不是报错。
使用 v-app 包裹应用。 它是布局组件注册所依赖的坐标系,因此应用栏和抽屉会知道应将 v-main 向内缩进,而不是覆盖它。
在 defaults 或 v-defaults-provider 中一次性设置重复的属性。 每个实例都重复声明 variant,意味着每个调用位置都要重新做出决定;这两种机制分别适用于全局和分区场景,而且无需样式表。
优先通过插槽自定义,而不是使用 CSS。 组件的每个内部元素都有一个具名插槽,因此替换元素时可以使用 <template v-slot:…>,而不是使用可能在版本升级时失效的选择器。
在模板外定义 v-data-table 表头。 在模板中使用数组字面量,每次父组件渲染都会产生一个新的标识,从而导致整个表格每次都重新渲染。
使用组合式函数,而不是 this.$vuetify。 useTheme()、useDisplay()、useDate() 和 useLocale() 是 Composition API 的接口;实例属性属于 Options API,在 <script setup> 中不可用。
</critical_requirements>
自动检测: vuetify、createVuetify、vuetify/styles、vuetify/blueprints、vuetify/settings、
vuetify/iconsets、vite-plugin-vuetify、webpack-plugin-vuetify、v-app、v-main、v-btn、v-card、
v-data-table、v-data-table-server、v-data-table-virtual、v-text-field、v-select、v-autocomplete、
v-dialog、v-navigation-drawer、v-app-bar、v-snackbar、v-form、v-defaults-provider、
v-theme-provider、useTheme、useDisplay、useDate、useRules、useLocale、mdi-、$vuetify
适用范围:
- 配置库:主题、蓝图、默认值、图标集、SSR
- 选择某项更改所属的自定义层
- 组合库中提供的组件——布局、输入控件、数据表格、覆盖层、反馈
- 基于插槽自定义组件内部结构
- 通过
rules数组和useRules进行表单验证 - 通过网格属性和
useDisplay实现响应式行为
其他部分负责:
- Vue 本身——响应性、组件编写、生命周期,以及你编写的组合式函数
- 路由,以及导航项的链接目标
- 组件自身以外的应用状态——组件接收值并发出更改事件
- 数据获取。
v-data-table-server会报告用户请求的内容,并渲染收到的数据 - 通用 CSS 技巧。Vuetify 自身的三个层级属于范围之内;围绕这些层级构建的样式表架构则不在范围之内
Vuetify 有意坚持自己的设计理念。它不是一组供你用来组装设计系统的基础组件——它本身就是一个已经组装好的设计系统,你可以对其进行调整。与之对抗是使用它时遇到问题的最大来源。
调整分为三个层级,选择正确的层级是最重要的技巧:
- 主题——颜色和深色模式,会在运行时解析为 CSS 自定义属性。一切都会自动继承,主题切换也会在整个组件树中响应式生效。
- 默认值——在
createVuetify()中全局设置,或通过v-defaults-provider限定作用域。这是最容易被忽视的层级:它不仅改变外观,也会改变行为;它可以嵌套,并像 CSS 作用域一样层叠,而且不会增加运行时开销。 - SASS——用于设置属性未开放的部分的编译时 CSS 变量,例如字体系列、基础圆角和元素高度。它在构建时固定,且仅在使用构建插件时可用。
每个属性都恰好属于其中一个层级。尝试覆盖样式表,尤其是使用 !important,几乎总是意味着该属性本可通过上一层级设置。
<decision_framework>
要自定义的层级
| 要更改的内容 | 层级 |
|---|---|
| 颜色或深色模式 | createVuetify() 中的 theme,通过 useTheme() 读取 |
| 全局默认属性 | createVuetify() 中的 defaults |
| 页面某一部分的默认属性 | v-defaults-provider |
| 圆角、尺寸、字体——任何 CSS 层级的内容 | 通过 @use "vuetify/settings" 设置 SASS 变量 |
| 组件的某个内部元素 | 具名插槽 |
| 多个组件的排列方式 | 常规模板组合 |
选择哪个表格组件
Static rows, no interaction → v-table (a styled HTML table)
Sorting, filtering, paging locally → v-data-table
The server does the sorting/paging → v-data-table-server (separate component, not a prop)
Thousands of rows, no paging → v-data-table-virtual (height is required)
Rows grouped under headings → v-data-table with group-by
</decision_framework>
核心模式
模式 1:插件设置
一次 createVuetify() 调用即可配置主题、默认属性、图标集和区域设置,所有组件都会读取这些配置。
import { createVuetify } from "vuetify";
const vuetify = createVuetify({
theme: {
defaultTheme: "light",
themes: { light: { colors: { primary: "#1867C0" } } },
},
defaults: {
VBtn: { variant: "flat", rounded: "lg" },
VTextField: { variant: "outlined", density: "comfortable" },
},
});
createApp(App).use(vuetify).mount("#app");
蓝图、SASS 覆盖、TypeScript 扩展、SSR 和 SVG 图标集请参阅 examples/core.md。
模式 2:主题和深色模式
主题会转换为 CSS 自定义属性,因此切换主题后,所有组件都会以响应式方式更新,无需重新渲染自身。
<script setup>
import { useTheme } from "vuetify";
const theme = useTheme();
function toggleTheme() {
theme.global.name.value = theme.global.current.value.dark ? "light" : "dark";
}
</script>
theme.global.name 是一个 ref——请为 .value 赋值。也可以在 CSS 中通过
rgb(var(--v-theme-primary)) 访问颜色。
完整代码:examples/core.md
模式 3:全局默认属性和作用域默认属性
defaults 用于为某种组件类型设置属性值。v-defaults-provider 对子树执行相同操作,并与当前作用域中已有的设置合并。
<v-defaults-provider
:defaults="{
VBtn: { color: 'secondary', variant: 'tonal' },
VCard: { elevation: 0, border: true },
}"
>
<v-card>
<v-btn>Tonal and secondary, with no props of its own</v-btn>
</v-card>
</v-defaults-provider>
实例上显式设置的属性始终优先于默认值,因此这只是缩小默认范围,而不是覆盖任何内容。
完整代码:examples/core.md
模式 4:基于插槽的自定义
每个内部元素都有一个具名插槽。替换插槽内容后,组件原有的行为、无障碍配置和密度处理都会保留;而这些功能都无法通过包在外部的 div 实现。
<v-text-field label="Amount" type="number">
<template v-slot:prepend-inner>
<v-icon>mdi-currency-usd</v-icon>
</template>
</v-text-field>
完整代码:examples/data-tables.md(各列插槽), examples/layout.md(activator 和 append 插槽)。
模式 5:数据表格
v-data-table 可处理排序、分页、搜索和选择。使用 v-slot:item.<key> 自定义列,其中 <key> 与表头的 key 对应。
<script setup>
const headers = [
{ title: "Name", key: "name" },
{ title: "Status", key: "status" },
{ title: "Actions", key: "actions", sortable: false },
];
</script>
<template>
<v-data-table :items="items" :headers="headers" item-value="id">
<template v-slot:item.status="{ item }">
<v-chip
:color="item.status === 'active' ? 'success' : 'error'"
size="small"
>
{{ item.status }}
</v-chip>
</template>
</v-data-table>
</template>
模式 6:表单验证
规则是普通函数,返回 true 或错误字符串。useRules 提供了已经定义好的常用规则。
<script setup>
import { useRules } from "vuetify/labs/rules";
const rules = useRules();
</script>
<template>
<v-form ref="form" validate-on="submit" @submit.prevent="onSubmit">
<v-text-field
v-model="email"
label="Email"
:rules="[rules.required(), rules.email()]"
/>
<v-btn type="submit" color="primary">Submit</v-btn>
</v-form>
</template>
validate-on 决定何时运行规则——"submit" 会让表单保持安静,直到用户完成操作;默认情况下则会在每次按键时验证。
完整代码:examples/forms.md
模式 7:使用 useDisplay 实现响应式行为
网格属性负责响应式 布局。useDisplay 负责响应式 逻辑——决定渲染哪个组件,而不是决定组件的宽度。
<script setup>
import { useDisplay } from "vuetify";
const { mobile, mdAndUp } = useDisplay();
</script>
<template>
<v-navigation-drawer :permanent="mdAndUp" :temporary="!mdAndUp" />
<v-app-bar :density="mobile ? 'compact' : 'default'" />
</template>
完整代码:examples/layout.md
<red_flags>
容易出错的地方
运行时会出问题:
- 未使用
app.use(vuetify)——Vue 无法识别这些组件,因此它们会渲染为空的自定义元素,且不会报错说明原因 - 在手动导入路径中未使用
import "vuetify/styles"——所有组件都会挂载,但没有任何样式 - 在
<script setup>中使用this.$vuetify——这里没有组件实例;请改用组合式函数 v-col没有v-row父级,或v-row位于v-container之外——网格依赖完整的嵌套结构,缺少它时会悄然崩溃- 在
v-data-table上内联编写表头或列数组——每次父组件渲染都会产生新的标识,因此整个表格每次都会重新渲染 - 使用
v-data-table手动实现服务端分页——v-data-table-server是独立组件,而客户端组件会对传入的页面再次分页 v-data-table-virtual未设置height——虚拟滚动器没有可测量的视口,因此不会渲染任何内容
容易产生意外的行为:
density的取值为"default"、"comfortable"或"compact"——不是数值- Vuetify 的断点与常见的 CSS 断点不同:
md从 960px 开始,而不是 768px v-defaults-provider会与上层的 provider 合并,而不是替换它;最内层的值优先theme.variations会自动生成primary-lighten-1、primary-darken-2等变体——手动声明这些变体会覆盖自动生成的集合- 在对话框或抽屉上使用
v-if会销毁组件,而不是将其关闭,因此会丢失过渡效果和内部状态;应使用v-model切换可见性 - SASS 变量覆盖需要配置带有
styles.configFile的构建插件——否则文件不会被编译,覆盖设置也会悄然失效 "on-primary"是主色背景上的文本颜色,而不是带有主色调的文本v-select和v-autocomplete会绑定item-value,除非设置了return-object;因此模型中保存的是键,而不是其对应的对象