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 脚手架。

  1. 项目初始化:npm create vite@latest m3-slot-demo -- --template vue-ts
  2. 安装核心依赖:npm install @material/web @material/theme sass
  3. 安装辅助类型(可选):npm install -D @material/web/types
  4. 创建主题配置文件:在 src/ 下新建 m3-theme.scss,定义自定义属性。
  5. 引入主题并挂载:在 main.ts 中导入 SCSS 并调用 applyTheme()。
  6. 验证:使用 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 流程图)

开发环境搭建流程 项目初始化 安装依赖 主题 SCSS m3-theme.scss 挂载主题 节点说明: ① 使用 vite 模板;② 安装 @material/web、@material/theme、sass;③ 配置 Design ;④ 调用 applyTheme() 生效。

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 名称,否则内容不会渲染。

3.9 与 Slot API 的衔接