因为SCSS变量默认不具备跨文件作用域,A.vue中定义的$primary-color在B.vue中不可见;必须通过vite.config.ts中css.preprocessorOptions.scss.additionalData配置@use "@/styles/variables.scss" as *;全局注入,且variables.scss内不得嵌套@use或@import。

为什么直接写 $color-primary 会报错 undefined
因为 SCSS 变量默认不具备跨文件作用域。你在 A.vue 的 <style lang="scss"></style> 里定义了 $primary-color: #409eff;,B.vue 完全看不到它——这不是 bug,是 SCSS 模块化编译的正常行为。uni-app(尤其是 Vite 构建的 3.0+ 项目)不会自动合并所有 SCSS 文件里的变量。
必须用 css.preprocessorOptions.scss.additionalData 注入变量
这是当前(2026 年)Vite 版 uni-app 唯一稳定生效的方式。其他方法如 @import 写在每个 <style></style> 里、prependData、或依赖 uni.scss,都会在 H5 热更新、小程序真机调试或条件编译下失效。
-
vite.config.ts中配置必须包含三要素:路径以@/开头(指向src/),使用@use "xxx" as *;语法,末尾带分号 - 示例配置:
css: { preprocessorOptions: { scss: { additionalData: '@use "@/styles/variables.scss" as *;' } } } -
variables.scss文件必须真实存在,且只放纯定义,比如:$primary-color: #409eff; $border-radius-sm: 2px; $font-size-base: 14px;
- 不能在里面再
@use或@import其他文件,否则 Vite 解析不稳定
@use "xxx" as * 和 @import 的关键区别
@import 是文本拼接,多个组件同时 import 同一个变量文件 = 多次定义同名变量 = 最后一次覆盖前面的,H5 切页面后颜色跳变、小程序样式不一致都源于此;@use 是模块引用,但 uni-app 单文件编译链对跨文件依赖分析不完善,容易漏注入。
-
as *很关键:它把variables.scss里所有变量、mixin、函数直接挂进当前作用域,否则你得写variables.$primary-color - 别名路径必须用
@/,相对路径(如../styles/variables.scss)在不同层级的 .vue 文件中会解析失败 - 确保项目已安装
sass@^1.33.0+,低版本会报Invalid CSS after "@use"
跨端样式定制真正要靠 CSS 变量 + SCSS 计算
SCSS 变量本身无法运行时修改,所以“动态主题”不是靠它切换,而是用它生成基于 CSS 自定义属性的样式规则。例如:
立即学习“前端免费学习笔记(深入)”;
- 在
variables.scss中写:$primary-color: var(--primary-color); - 在
App.vue的:style绑定中设置:{ '--primary-color': currentTheme.primary } - 所有用到
$primary-color的地方,实际编译后都是var(--primary-color),JS 修改它即可实时生效 - 避免在 SCSS 中直接写
darken($primary-color, 10%)—— 这会在编译时求值,失去动态性;应改用 CSS 函数如color-mix(in srgb, var(--primary-color), black 20%)(需目标端支持)
最易被忽略的一点:SCSS 变量只负责组织和计算,CSS 变量才承载运行时值;两者混用时,千万别让 additionalData 注入的 SCSS 变量去读取尚未由 JS 设置的 CSS 变量,否则编译期就报错。


















