3. 开发环境搭建:项目初始化、依赖安装、Material 3主题配置
3.1 本章目标与基本原理
本章引导你从零搭建一个支持 Material 3(M3)Slot API 的 Vue 3 + Vite 开发环境。核心原理是:
- 主题系统:M3 使用 Design (设计令牌)定义颜色、字体、形状等语义值,通过 CSS 自定义属性或 JavaScript 注入应用范围。
- Slot API 依赖:组件库(如
@material/web)提供可插拔的插槽(slots),但需要正确配置主题上下文才能激活动态样式。 - 构建链路:Vite 负责模块打包,
postcss配合sass处理 M3 的 文件,最终生成响应式 CSS。
3.2 环境搭建完整流程
以下步骤在 Node.js ≥ 18 和 npm ≥ 9 环境下验证。推荐使用 Vue 3 + Vite 脚手架。
- 项目初始化:
npm create vite@latest m3-slot-demo -- --template vue-ts - 安装核心依赖:
npm install @material/web @material/theme sass - 安装辅助类型(可选):
npm install -D @material/web/types - 创建主题配置文件:在
src/下新建m3-theme.scss,定义自定义属性。 - 引入主题并挂载:在
main.ts中导入 SCSS 并调用applyTheme()。 - 验证:使用
MdTextButton组件测试主题色是否生效。
3.3 依赖与版本对比
| 包名 | 推荐版本 | 用途 | 是否必需 |
|---|---|---|---|
@material/web |
^2.0.0 | Material 3 Web 组件库(含 Slot API) | 是 |
@material/theme |
^14.0.0 | 主题令牌定义与动态生成工具 | 是 |
sass |
^1.70.0 | 编译 M3 令牌 SCSS 文件 | 是 |
vue |
^3.4 | 运行框架 | 是 |
vite |
^5.0 | 构建工具 | 是 |
typescript |
^5.3 | 类型支持(可选) | 否 |
3.4 主题配置代码实现
在 src/m3-theme.scss 中定义主题令牌:
// src/m3-theme.scss
@use '@material/theme' with (
$primary: #6750a4,
$on-primary: #ffffff,
$primary-container: #eaddff,
$on-primary-container: #21005d,
$secondary: #625b71,
$on-secondary: #ffffff,
$secondary-container: #e8def8,
$on-secondary-container: #1d192b,
$tertiary: #7d5260,
$on-tertiary: #ffffff,
$tertiary-container: #ffd8e4,
$on-tertiary-container: #31111d,
$error: #b3261e,
$on-error: #ffffff,
$error-container: #f9dedc,
$on-error-container: #410e0b,
$background: #fffbfe,
$on-background: #1c1b1f,
$surface: #fffbfe,
$on-surface: #1c1b1f,
$surface-variant: #e7e0ec,
$on-surface-variant: #49454f,
$outline: #79747e,
$outline-variant: #cac4d0
);
@import '@material/theme/color-scheme';
@import '@material/theme/shape';
@import '@material/theme/typography';
:root {
@include theme.core-styles;
}
在 main.ts 中引入并应用:
// src/main.ts
import { createApp } from 'vue'
import App from './App.vue'
import './m3-theme.scss' // 导入主题
import { applyTheme } from '@material/web/theme'
// 强制刷新主题变化
applyTheme(document.documentElement)
createApp(App).mount('#app')
提示:
applyTheme 函数会读取 :root 中的 CSS 自定义属性并将令牌映射到 Web 组件内部。如果主题色未生效,确认 SCSS 编译正确且 sass 依赖版本 ≥1.68(支持 @use 语法)。
3.5 验证环境:使用第一个 Slot 组件
在 App.vue 中引入 MdTextButton,测试 Slot 是否可以被主题着色:
<template>
<md-text-button>
<span slot="icon">★</span>
<span>Hello M3 Theme</span>
</md-text-button>
</template>
<script setup lang="ts">
import '@material/web/button/text-button.js'
</script>
运行 npm run dev,如果按钮背景色、文字颜色、图标颜色均与 m3-theme.scss 中定义的 $primary 一致,则主题配置成功。
3.6 常见错误与调试
| 错误现象 | 原因 | 解决方案 |
|---|---|---|
| SCSS 编译报错 "Undefined mixin" | @material/theme 版本与 @material/web 不兼容 |
锁定 @material/theme@14,并使用 @material/web@2 |
| 组件颜色全为默认灰色 | applyTheme 未被调用 |
在 main.ts 中显式调用 applyTheme(document.documentElement) |
| Slot 内容不显示 | 组件未正确注册 | 检查 import '@material/web/button/text-button.js' 路径是否完整 |
| 动态主题不生效 | CSS 自定义属性被 scoped 样式覆盖 |
使用全局样式或 :deep() 穿透 |
3.7 环境结构概览(SVG 流程图)
3.8 性能与稳定性建议
- 按需导入:只导入用到的组件(如
import '@material/web/button/text-button.js'),避免全量加载。 - tree-shaking:确保
vite.config.ts启用build.rollupOptions.treeshake,消除未使用的令牌样式。 - 主题变量预热:将
applyTheme调用放入Vue.nextTick或onMounted,避免 DOM 未解析时执行。 - 防止主题闪烁:在
index.html的<head>中内联基础主题 CSS,减少首次渲染无色。
警告:
@material/web v2 之前使用 md-text-button 等组件时,slot 属性名可能为 icon-leading 等新的语义名。请查阅对应组件的 README 确认 slot 名称,否则内容不会渲染。