首先:在项目模板里面使用的是 unplugin-element-plus
。这个插件的功能只是在你导入组件的时候自动导入css
样式,并不会给你自动导入组件。Element Plus 文档
为什么不使用自动导入的插件呢?我在 Vben Admin
的仓库也提了相关issue。作者的回复是尊重每个开发者的习惯,如果需要就自己去配置。
接下来就说下如何配置自动导入。我之前就写过一遍介绍配置自动导入的文章,我就不在重复的写了,可以点击下面的链接去看一下。
vue3.0 + vite + ts 完成自动导入 vue API 和 自动导入组件及 element loading 指令无法正常使用解决方法
重点来了
当我们配置好自动导入的时候,我们会遇到一个问题,那就是切换主题的时候,无论怎么切换都是白色主题,无法切换到暗黑主题。我们一起来看下效果
可以看到,使用了自动导入之后主题变得不对了。
在 main.ts 文件导入这个样式就可以解决 import 'element-plus/theme-chalk/dark/css-vars.css'
在引入之后就会有 css var 变量了,html.dark .el-card
在这里说一下问题的原因:本质上就是选择器的优先级问题。
在 Vben Admin 里面切换主题的代码主要在这几个文件,文件路径在 packages/effects/hooks/src/use-design-tokens.ts
, packages/@core/base/shared/src/utils/update-css-variables.ts
。可以看到虽然 css
变量被更新了,但是却被 Element plus
的原始css变量覆盖掉了。除了导入 Element Plus 的黑暗主题,还有一种方法就是修改 updateCSSVariables
方法,将选择器修改为 body,也就是加强css的优先级,就可以覆盖掉 Element plus
的原始主题。
这是修改后的代码,不过还是建议直接导入 Element plus
的暗黑主题。
function updateCSSVariables(variables: { [key: string]: string },id = '__vben-styles__',
): void {// 获取或创建内联样式表元素const styleElement =document.querySelector(`#${id}`) || document.createElement('style');styleElement.id = id;// 构建要更新的 CSS 变量的样式文本let cssText = 'body {';for (const key in variables) {if (Object.prototype.hasOwnProperty.call(variables, key)) {cssText += `${key}: ${variables[key]};`;}}cssText += '}';// 将样式文本赋值给内联样式表styleElement.textContent = cssText;// 将内联样式表添加到文档头部if (!document.querySelector(`#${id}`)) {setTimeout(() => {document.head.append(styleElement);});}
}