Element Plus 暗黑模式的适配核心在于:用 SCSS 实现动态主题生成,让暗黑模式跟随你的 Design Token 变化,而不是使用官方提供的静态 CSS 文件。
1. 静态 vs. 动态:两种方案的本质区别
| 方案类型 | 引入方式 | 特点 | 适用场景 |
|---|---|---|---|
| 静态方案(官方文档推荐) | import 'element-plus/theme-chalk/dark/css-vars.css' |
颜色写死在 CSS 文件中 。当你在代码里修改 --el-color-primary 时,暗黑模式下的相关颜色不会随之变化。 |
只需要一个"纯黑"模式,不需要动态切换主题色。 |
| 动态方案(Design Token 推荐) | 通过 SCSS @forward 重新编译暗黑模式变量 |
暗黑模式下的颜色由 SCSS 变量和混合算法动态生成。修改一个主色,亮色和暗色模式的颜色序列都会自动重新计算。 | 需要支持用户自定义主题色,且亮/暗模式都得同步变化。 |
2. 动态方案最佳实践(与 Design Token 结合)
第一步:修改 Vite 配置,注入 SCSS 变量
由于按需导入,需要在 vite.config.ts 的 css.preprocessorOptions.scss 中,用 additionalData 将你的主题变量注入到所有组件中。
typescript
// vite.config.ts
export default defineConfig({
css: {
preprocessorOptions: {
scss: {
additionalData: `@use "@/styles/element/theme.scss" as *;`
}
}
}
});
第二步:创建动态主题 SCSS 文件
在 theme.scss 中,使用 @forward 覆盖 Element Plus 的 var.scss。关键在于用 $colors 和 $bg-color 分别控制亮色和暗色模式下的混合颜色。
scss
// src/styles/element/theme.scss
@forward 'element-plus/theme-chalk/src/common/var.scss' with (
// 亮色模式下,light 系列用白色混合
$colors: (
'primary': ('base': #409EFF), // 换成你的 Design Token 变量
),
// 暗黑模式下,light 系列用深色背景混合(关键!)
$bg-color: (
'' : #141414, // 这是暗黑模式下的基础背景色
'page' : #0a0a0a,
)
);
第三步:引入 SCSS 入口文件(而非 CSS 文件)
在 main.ts 中,引入 dark/css-vars.scss,这会触发 SCSS 编译器读取你在第二步中 @forward 的变量,动态计算出暗黑模式下的所有颜色值。
typescript
// main.ts
// 不要用这个静态的:import 'element-plus/theme-chalk/dark/css-vars.css'
// 使用 SCSS 入口
import 'element-plus/theme-chalk/src/dark/css-vars.scss';
3. 切换控制:使用 VueUse
推荐使用 @vueuse/core 的 useDark 组合式函数,它会自动管理 <html> 标签上的 dark class,非常方便。
vue
<template>
<el-switch v-model="isDark" />
</template>
<script setup>
import { useDark, useToggle } from '@vueuse/core'
const isDark = useDark() // 默认操作 html 的 dark class
const toggleDark = useToggle(isDark)
</script>
4. 暗黑模式 + Tailwind CSS
在你的 Tailwind v4 代码中,可以使用 dark: 前缀配合你的 Design Token 变量,保持一致性。
html
<div class="bg-white dark:bg-(--el-bg-color) text-gray-800 dark:text-white">
<!-- 内容 -->
</div>
💎 总结:关键避坑点
- 不要 使用官方文档第一眼看到的
import 'element-plus/theme-chalk/dark/css-vars.css',它是静态的,无法响应你的 Design Token 变化。 - 务必 通过 SCSS
@forward重新编译var.scss,并特别关注$bg-color这个变量对暗黑模式颜色的影响。 - 你的 Design Token 需要同时注入到 Vite 的
additionalData和 Tailwind v4 的@theme中,实现"一处定义,全局使用"。