sass变量仅在编译期生效,运行时无法修改;它会被编译为静态css值,浏览器中不存在$color等符号,主题切换应使用css自定义属性(var(--color))而非sass变量。

你不能在运行时更改 Sass 变量,这不是限制,而是设计使然——它压根就不该被运行时修改。
运行时改 $color 是无效操作,浏览器里根本找不到这个符号
Sass 变量只存在于编译前的 .scss 源文件中,一旦经过 dart-sass 或 node-sass 处理,$color 就彻底消失了,最终生成的 CSS 里只有硬编码值,比如 color: #4285f4。JS 执行时 DOM 中没有 $color 这个东西,document.querySelector 查不到,getComputedStyle 读不到,更别说修改了。
常见错误现象:
- 在 Vue 组件里写
<style scoped>$primary-color: v-bind(dynamicColor);</style>—— 这行不通,Sass 不解析 JS 表达式 - 试图用
style="--primary-color: {{ dynamicColor }}"去覆盖一个用$primary-color定义的主题色 —— 结果样式完全不响应 - 在控制台执行
document.documentElement.style.setProperty('$primary-color', 'red')—— 报错:CSS 属性名非法
var(--color) 和 $color 的本质区别:一个是 DOM 属性,一个是编译占位符
CSS 自定义属性(即 var(--color))是浏览器原生支持的运行时机制;Sass 变量只是预处理器的文本替换工具。两者不在同一层:
-
--color是真实存在的 CSS 属性,可被getPropertyValue读取、setProperty修改,并触发重绘 -
$color是编译期符号,仅用于生成静态 CSS,编译后即销毁,无运行时实体 - 你在 JS 里调用
document.body.style.setProperty('--color', 'blue')立刻生效;而对$color做任何事都等于对空气说话
性能影响上:var() 更新只触发局部样式计算;Sass 多主题方案则需加载整套新 CSS 文件,带来 FOUC、缓存失效、transition 断裂等问题。
想实现“切换主题”,别碰 Sass 变量,直接用 :root + var()
主题切换不是“换变量”,而是“换值”。正确路径是把所有可变值声明为 CSS 自定义属性,在 :root 下集中管理:
:root {
--primary-color: #4285f4;
--bg-color: #ffffff;
--text-color: #333333;
}
然后在组件中使用:
.button {
background-color: var(--primary-color);
color: var(--text-color);
}
切换深色模式只需:
document.documentElement.style.setProperty('--bg-color', '#1a1a1a');
document.documentElement.style.setProperty('--text-color', '#e0e0e0');
容易踩的坑:
- 在
<style scoped></style>里写:root { --x: red }—— 不生效,scoped 会加属性选择器,:root[data-v-xxx]不匹配文档根节点 - 用 Sass 生成
:root块时忘了插值:--color: $color错,必须写成--color: #{$color} - 以为
@media (prefers-color-scheme: dark)能改$color—— 不行,媒体查询无法改变编译期变量,只能用来包裹已生成的 CSS 规则
构建时开关(如 $enable-flex)≠ 运行时开关,别混淆用途
Sass 的布尔变量只服务于构建流程,比如控制是否输出某段 CSS:
$enable-flex: true;
.container {
@if $enable-flex {
display: flex;
} @else {
display: block;
}
}
这整个逻辑发生在打包阶段。你改了 $enable-flex,必须重新运行 sass 命令或触发热重编译,否则浏览器里什么都不会变。
关键限制:
- 变量类型必须是 Sass 原生 bool(
true/false),字符串"true"在@if中仍是真值 - Webpack/Vite 的 sass-loader 默认不监听
_variables.scss变更并自动重编译,得手动配置 watch 或用sass-resources-loader配合文件变更事件 - 不要试图在 JS 里动态 import 不同的 Sass 主题文件——那只是多套静态产物,不是“动态”
真正需要运行时响应的地方,CSS 变量是唯一正解;Sass 变量只适合做构建配置、主题基线、设计系统原子值的统一维护。混用二者时,最容易忽略的其实是作用域链和构建时机——前者决定变量能不能被读到,后者决定改了到底有没有进最终 CSS。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











