element ui 的 scss 变量覆盖必须写在 @import 之前,因变量带 !default,先声明后导入才能生效;element plus 则需用 @forward with 显式传值。

Element UI 的 SCSS 变量覆盖必须写在 @import 之前
重写变量生效的前提是:Sass 编译器在读到 Element UI 原始 var.scss 之前,已经看到你定义的同名变量。Element UI 所有变量都带 !default,所以只要“先声明、后导入”,就能覆盖。
常见错误是把变量重写写在 @import "~element-ui/packages/theme-chalk/src/index" 之后,或者混在组件 <style lang="scss" scoped></style> 里——这些位置变量根本不会参与全局主题编译。
- 正确做法:新建
src/styles/element-variables.scss,第一行就写$--color-primary: #1890ff;,第二行再@import "~element-ui/packages/theme-chalk/src/index"; - 变量名注意:Element UI 的变量用双短横线(
$--color-primary),但部分构建工具(如旧版 sass-loader)对双短横解析不稳定,可改用下划线($__color_primary)替代,效果一致 - 不要全量复制
var.scss再删减——只写你要改的变量,其余由源码兜底,避免遗漏导致样式断裂
::v-deep 穿透失效,大概率是空格或嵌套位置错了
::v-deep 不是选择器修饰符,而是 Vue 编译时识别的伪类前缀,它对书写格式极其敏感。
最常踩的坑是:::v-deep .el-input__inner 写成 ::v-deep(.el-input__inner) 或 .form-item ::v-deep .el-input__inner ——前者被当成函数调用,后者因嵌套层级导致作用域前缀丢失,编译后生成的选择器完全不匹配真实 DOM。
- 必须写在
<style lang="scss" scoped></style>的顶层,不能缩进,不能包裹在其他 class 下 -
::v-deep后必须紧跟一个空格,再写目标类名,例如:::v-deep .el-button - 遇到
teleport类组件(如<el-dialog></el-dialog>),DOM 已脱离当前组件树,::v-deep失效,此时只能用:global(.el-dialog)(Vue 3)或提至全局样式文件中覆盖
Element Plus 用 @use 替代 @import,变量覆盖逻辑变了
Element Plus 官方已弃用 @import,改用 @use + @forward 机制管理变量。这意味着你不能再靠“顺序先后”覆盖,而要通过 @forward ... with 显式传入新值。
比如你想改主色和圆角,得这样写:
@forward 'element-plus/theme-chalk/src/common/var.scss' with (
$colors: (
'primary': ('base': #13c2c2),
),
$border-radius-base: 6px,
);
然后才 @use "element-plus/theme-chalk/src/index.scss"。如果还沿用老项目里的 @import 写法,变量根本不会被注入,所有覆盖都静默失败。
- 别再引入
element-plus/dist/index.css,它会和你自定义的 SCSS 冲突,导致样式重复或覆盖被忽略 -
@use模块默认启用命名空间,若需全局使用变量,加as *;但要注意命名冲突风险 - Vite 项目中,确保
vite.config.ts没有通过css.preprocessorOptions.sass.additionalData注入重复的变量文件,否则可能引发循环依赖
全局变量注入到所有组件,别靠 additionalData 硬塞
想让自定义 SCSS 变量(比如 $uni-primary 或 $my-font-stack)在每个 <style lang="scss"></style> 中自动可用,最稳妥的方式是统一入口导入,而不是靠构建配置“注入”。
用 additionalData 往每个 SCSS 文件头塞 @import,看似省事,实则埋雷:它无法控制执行顺序,容易和 UI 库的变量导入打架;且一旦变量文件路径变更,所有组件都会编译报错,排查成本高。
- 推荐方案:建一个
src/styles/global.scss,里面只放变量定义和基础@import,然后在main.js/ts中import "@/styles/global.scss" - 如果用 Vite,可配合
unplugin-vue-components的dirs配置,让组件自动加载该文件,但前提是确认插件版本支持 SCSS 全局注入 - Vue CLI 项目中,
vue.config.js的css.loaderOptions.sass.additionalData仅用于补漏,比如统一注入字体声明,不要用来覆盖 UI 库变量
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











