变量未生效主因是 Sass 混用 @import 与 @use 导致降级为 legacy 模式,使 @use 失效;应统一用 @use 并避免任何 @import,通过 additionalData 注入带下划线的变量文件,启用命名空间访问。
变量没生效,大概率不是路径写错,而是 Sass 模块系统被意外降级或覆盖了。
常见错误现象是:变量文件明明存在、路径也对,但编译时仍提示未定义。这不是 Nuxt 3 的 bug,而是 Sass 编译器在混合使用 @import 和 @use 时自动降级为 legacy 模式,导致所有 @use 失效、命名空间丢失、变量无法跨文件访问。
@import(包括 node_modules 里的第三方库,如旧版 Bootstrap 或某些 UI 库的 SCSS 入口).scss 文件里出现 @import,整份文件就进 legacy 模式,@use "vars" as theme 直接被忽略@import 'reset',theme.$primary 突然就能用了@use 的版本(例如 Bootstrap ≥ 5.3、Ant Design Vue ≥ 4.0)Nuxt 3 推荐用 vite.css.preprocessorOptions.scss.additionalData 注入,但它只是“每份 SCSS 文件开头加一行 @import”,本质仍是 @import 模式,有污染风险。更稳妥的做法是分两层控制:
assets/_variables.scss(注意下划线前缀),只放带 !default 的声明,例如:$color-primary: #007bff !default;
nuxt.config.ts 中配置:vite: {css: {preprocessorOptions: {scss: {additionalData: '@use "@/assets/_variables" as *;'}}}}
@use "@/assets/_variables" as *; 中的 _variables 必须带下划线,不能写 variables.scss 或 variables
@import,尤其避免在 app.vue 或组件 <style lang="scss"> 里再手动 @import
这是模块化带来的必然变化:@use 默认启用命名空间,不再“裸奔”。你不能再直接写 $primary-color,而必须通过命名空间访问。
@use "@/assets/_variables"; .btn { color: $primary-color; } → 报错@use "@/assets/_variables" as vars; .btn { color: vars.$primary-color; }
as *,但需确保:该文件没混用 @import;且没有多个 as * 导致同名变量覆盖{ src: 'bulma/scss/bulma.scss', lang: 'scss' },避免 sass-loader@11+ 兼容问题别靠猜,用 @debug 直接看编译输出:
@debug $color-primary;
nuxi dev,终端会打印出该变量最终的值和它所在的文件路径#1890ff),说明它的 @import 或 @use 出现在你之后$color-primary:(注意冒号),重点盯 node_modules 下的 _variables.scss 和构建配置里的 additionalData
真正容易被忽略的点是:你以为变量失效了,其实它早就被注入了,只是 CSS 层级没赢——比如你在 .btn 里设了 color: $color-primary,但页面上还是灰色,大概率是某条 .btn.is-disabled { color: #ccc !important; } 压过了它。