1. 引言
1.1 Vuetify 3 概述
- Material Design 实现:Vuetify 3 是基于 Google Material Design 规范的 Vue.js 组件库,提供了一套完整的设计系统
- Vue 3 集成:专门为 Vue 3 设计,充分利用 Composition API 的优势,提供更好的开发体验
- 组件丰富:提供超过 80 个预构建的 UI 组件,覆盖常见的用户界面需求
- 开箱即用:无需额外的 CSS 框架,直接提供完整的样式和主题系统
- 无障碍支持:内置 ARIA 标签和键盘导航支持,符合无障碍标准
1.2 Vue 3 与 Vuetify 3 的优势
- 性能提升:Vue 3 的响应式系统带来更好的性能,虚拟 DOM 优化减少了重渲染开销
- TypeScript 支持:完整的类型定义和类型推断,提供更好的开发体验和错误预防
- 组合式 API:更灵活的组件逻辑组织方式,便于代码复用和测试
- 更好的 Tree Shaking:支持按需导入,减小打包体积
- Composition API 集成:Vuetify 3 深度集成 Composition API,提供更好的响应式体验
2. 环境准备与安装
2.1 开发环境要求
- Node.js:版本 14.x 或更高,推荐使用 LTS 版本
- npm 或 yarn:包管理工具,用于安装和管理依赖
- Vue CLI:Vue 项目脚手架工具,或使用 Vite 作为现代构建工具
- 代码编辑器:推荐 VS Code,配合 Vetur 或 Volar 插件获得更好的开发体验
- 浏览器:现代浏览器,支持 ES6+ 语法
2.2 Vue 3 项目创建
# 使用 npm 创建新的 Vue 3 项目npmcreate vue@latest my-vuetify-appcdmy-vuetify-app# 选择项目配置(建议启用 TypeScript、JSX、Router、Pinia、Vitest、Cypress)# 安装依赖npminstall2.3 Vuetify 3 安装配置
# 安装 Vuetify 3 和相关依赖npminstallvuetify@next @mdi/font@^7.0.962.4 初始配置文件设置
创建src/plugins/vuetify.js:
import{createVuetify}from'vuetify'import*ascomponentsfrom'vuetify/components'import*asdirectivesfrom'vuetify/directives'exportdefaultcreateVuetify({components,directives,})在src/main.js中注册 Vuetify:
import{createApp}from'vue'importAppfrom'./App.vue'importvuetifyfrom'./plugins/vuetify'import'@mdi/font/css/materialdesignicons.css'import'vuetify/styles'createApp(App).use(vuetify).mount('#app')3. Vuetify 3 基础概念
3.1 Material Design 设计原则
- 层次清晰:通过阴影和颜色区分元素层级,提供直观的空间感知
- 一致性强:统一的设计语言和交互模式,确保用户体验的一致性
- 响应迅速:流畅的动画和过渡效果,提升用户交互体验
- 适应性好:支持不同屏幕尺寸和设备类型的响应式设计
- 可用性高:遵循无障碍设计原则,确保所有用户都能正常使用
3.2 Vuetify 组件架构
- 原子组件:基础组件如
v-btn、v-text-field、v-icon,提供基本功能 - 复合组件:由多个原子组件组成,如
v-card、v-data-table、v-dialog - 布局组件:用于页面布局的容器组件,如
v-container、v-row、v-col - 工具组件:提供辅助功能的组件,如
v-overlay、v-snackbar、v-tooltip
3.3 主题系统简介
- 默认主题:内置的蓝色主题,符合 Material Design 规范
- 自定义主题:可自定义颜色、字体等样式属性,满足品牌需求
- 深色模式:支持自动或手动切换深色主题,适应不同使用场景
- 主题切换:支持运行时动态切换主题,提供更好的用户体验
- CSS 变量:使用 CSS 自定义属性,便于主题定制和动态修改
3.4 断点与响应式设计
Vuetify 3 提供了基于 12 列网格系统的响应式布局:
- xs: <600px - 超小屏幕设备
- sm: 600px > <960px - 小屏幕设备(如手机横屏)
- md: 960px > <1264px - 中等屏幕设备(如平板)
- lg: 1264px > <1904px - 大屏幕设备(如桌面显示器)
- xl: ≥1904px - 超大屏幕设备(如宽屏显示器)
4. 核心组件详解
4.1 布局组件(v-container,v-row,v-col)
v-container:
<template> <v-container> <v-row> <v-col cols="12" md="6"> <v-card> <v-card-text>这是左侧内容区域,使用 v-card 组件展示内容</v-card-text> </v-card> </v-col> <v-col cols="12" md="6"> <v-card> <v-card-text>这是右侧内容区域,可以放置不同的组件和信息</v-card-text> </v-card> </v-col> </v-row> <v-row> <v-col cols="12" sm="4" md="3" lg="2"> <v-card> <v-card-text>小卡片 1</v-card-text> </v-card> </v-col> <v-col cols="12" sm="4" md="3" lg="2"> <v-card> <v-card-text>小卡片 2</v-card-text> </v-card> </v-col> <v-col cols="12" sm="4" md="3" lg="2"> <v-card> <v-card-text>小卡片 3</v-card-text> </v-card> </v-col> </v-row> </v-container> </template>4.2 导航组件(v-app-bar,v-navigation-drawer)
v-app-bar:
<template> <v-app-bar color="primary" dark> <v-app-bar-nav-icon @click="drawer = !drawer"></v-app-bar-nav-icon> <v-app-bar-title>我的应用</v-app-bar-title> <v-spacer></v-spacer> <v-btn icon> <v-icon>mdi-bell</v-icon> </v-btn> <v-btn icon> <v-icon>mdi-account-circle</v-icon> </v-btn> </v-app-bar> </template>v-navigation-drawer:
<template> <v-navigation-drawer v-model="drawer" temporary> <v-list nav> <v-list-item link value="home" prepend-icon="mdi-home"> <v-list-item-title>首页</v-list-item-title> </v-list-item> <v-list-item link value="about" prepend-icon="mdi-information"> <v-list-item-title>关于我们</v-list-item-title> </v-list-item> <v-list-item link value="contact" prepend-icon="mdi-email"> <v-list-item-title>联系我们</v-list-item-title> </v-list-item> </v-list> </v-navigation-drawer> </template> <script> export default { data: () => ({ drawer: false }) } </script>4.3 表单组件(v-text-field,v-select,v-btn)
v-text-field:
<template> <v-form> <v-text-field v-model="username" label="用户名" placeholder="请输入用户名" variant="outlined" clearable prepend-inner-icon="mdi-account" hint="用户名长度为3-20个字符" persistent-hint ></v-text-field> <v-text-field v-model="password" label="密码" type="password" variant="outlined" append-inner-icon="mdi-eye" @click:append-inner="togglePasswordVisibility" ></v-text-field> <v-textarea v-model="description" label="描述" variant="outlined" rows="3" auto-grow max-rows="6" ></v-textarea> </v-form> </template> <script> export default { data() { return { username: '', password: '', description: '', showPassword: false } }, methods: { togglePasswordVisibility() { this.showPassword = !this.showPassword } } } </script>v-select:
<template> <div> <v-select v-model="selectedCountry" :items="countries" item-title="name" item-value="code" label="选择国家" variant="outlined" clearable chips multiple ></v-select> <v-autocomplete v-model="searchResult" :items="searchItems" label="搜索选项" variant="outlined" hide-no-data hide-details ></v-autocomplete> </div> </template> <script> export default { data() { return { selectedCountry: null, searchResult: null, countries: [ { name: '中国', code: 'CN' }, { name: '美国', code: 'US' }, { name: '日本', code: 'JP' }, { name: '韩国', code: 'KR' } ], searchItems: ['选项1', '选项2', '选项3', '搜索结果'] } } } </script>v-btn:
<template> <div> <div> <v-btn color="primary" size="small">小型按钮</v-btn> <v-btn color="primary">常规按钮</v-btn> <v-btn color="primary" size="large">大型按钮</v-btn> </div> <div> <v-btn color="primary" variant="outlined">边框按钮</v-btn> <v-btn color="success" variant="tonal">强调按钮</v-btn> <v-btn color="warning" variant="text">文本按钮</v-btn> </div> <div> <v-btn color="primary" :loading="loading" @click="handleClick"> <template v-slot:loader> <span>Loading...</span> </template> 加载按钮 </v-btn> <v-btn color="primary" :disabled="disabled"> 禁用按钮 </v-btn> </div> </div> </template> <script> export default { data() { return { loading: false, disabled: true } }, methods: { handleClick() { this.loading = true setTimeout(() => { this.loading = false }, 2000) } } } </script>4.4 数据展示组件(v-data-table,v-card,v-list)
v-card:
<template> <v-container> <v-row> <v-col cols="12" md="6"> <v-card max-width="400"