uni-app中SCSS变量未加载是因作用域隔离:每个<style lang="scss">为独立编译入口,@import仅限当前文件;全局变量必须定义在根目录uni.scss中并前置@import,或通过Vite additionalData预注入绝对路径文件。

变量没被加载进来,不是没定义,而是根本没进编译作用域。
为什么 @import 或 @use 了还是报错
常见错觉是“我已经 @import 'variables.scss' 了”,但 Sass 变量作用域是文件级的——它只对当前文件及其后续 @import 的子文件生效,不会自动透传到其他独立编译的 .vue 文件样式块里。uni-app 中每个 <style lang="scss"> 都被当作一个独立入口处理,所以你在某个组件里 @import,只管那个组件;全局变量必须进 uni.scss 或 Vite 的 additionalData 预注入。
- 检查是否把变量引入写在了组件内部(比如
pages/index/index.vue的<style>里),这无法影响 uView 等第三方库的编译 - 确认
uni.scss是项目根目录下那个文件,且它确实被 uni-app 自动识别(不能叫app.scss或放在src/styles/下不引用) - 若用
@use,注意命名空间:用了@use 'vars' as v,就得写v.$color-primary,不能直接用$color-primary
uni.scss 里怎么引才有效
uni.scss 是 uni-app 唯一能“广播”变量到所有页面和组件的地方,但它本身不自动加载任何内容,必须手动 @import。顺序极其关键:变量定义必须出现在所有使用它的 @import 之前。
- 正确顺序示例:
@import "@/styles/variables.scss"; // 必须放最前 @import "@/styles/mixins.scss"; @import "uview-ui/theme.scss"; // 依赖 variables.scss 中的值 @import "uview-ui/index.scss";
- 路径别名
@/在uni.scss中默认不可用,得写相对路径或全路径,比如@import "./src/styles/variables.scss";更稳的是用uni_modules/uview-ui/theme.scss这种明确路径 - 如果 uView 报
$u-border-color错,只引index.scss不够,theme.scss必须显式前置引入
Vite 配置中 additionalData 的坑
当项目用 CLI + Vite 构建时,additionalData 是绕过 uni.scss 限制的可靠方式,但它会把代码插入到每个 SCSS 文件顶部,相当于“全局预置”。问题在于:它不解析别名,且容易重复注入。
- 路径必须用绝对路径或从
src开始的相对路径,@/styles/variables.scss会失败,应写成src/styles/variables.scss - 如果
uni.scss和additionalData都引了同一份变量,可能触发重复定义警告(虽不影响运行,但干扰排查) - 修改
vite.config.js后必须重启 dev server,热更新不感知配置变更 - 示例配置:
css: { preprocessorOptions: { scss: { additionalData: `@import "src/styles/variables.scss";` } } }
排查时优先看错误堆栈里的具体文件和行号
报错信息里那句 on line 38 of uni_modules/uview-ui/libs/css/common.scss 是黄金线索——说明问题不在你写的业务代码,而在 uView 自身样式编译失败。这时候翻 common.scss 第 38 行,顺着它 @import 的链路往回找,大概率会发现它依赖的 theme.scss 根本没被加载。
- 打开报错文件,看它
@import了什么(比如@import "../theme.scss"),然后确认这个路径在你项目里是否存在、是否可访问 - 检查
node_modules或uni_modules下对应 UI 库的目录结构,uView2 的theme.scss在uni_modules/uview-ui/theme.scss,不是libs/theme.scss - 临时在报错行上方加一行
@debug "loaded";,看控制台是否输出,能快速验证该文件是否真的参与了编译

















