@use是当前Sass中避免样式污染最可靠的方式,它从语言层面强制隔离变量、@mixin、%placeholder和函数的作用域;继续用@import等于主动放弃封装能力,污染几乎不可避免。

直接结论:@use 是当前 Sass 中避免样式污染最可靠的方式,它从语言层面强制隔离变量、@mixin、%placeholder 和函数的作用域;继续用 @import 就等于主动放弃封装能力,污染几乎不可避免。
为什么 @import 一定会导致样式污染
@import 不是“引入”,而是“合并作用域”——所有被导入文件里的 $variable、@mixin、%placeholder 全部平铺到当前文件中,且无命名空间。一旦两个模块都定义了 $border-radius,后 @import 的那个会覆盖前者,但你根本无法在编译时察觉。
- IDE 无法跳转到真正被使用的变量定义(因为多个同名变量共存)
- 重构时改一个
$color-primary,可能意外影响按钮、表单、弹窗三个不相干模块 - 第三方 Sass 库(如
sass:map)若也用@import,极易与项目内同名函数冲突 - Webpack 或 Vite 构建时,重复
@import同一文件会导致样式规则重复输出
怎样正确用 @use 隔离模块
@use 默认创建私有命名空间,所有成员不可见,除非显式暴露或别名引用。这不是可选项,是必须遵守的约束。
- 每个文件只
@use一次,多次不会重复执行,也不会合并命名空间 - 要访问变量,必须带命名空间前缀,例如
vars.$spacing-md(假设@use "base/variables" as vars) - 想全局可用?用
as *,但仅限极少数基础层(如@use "base/variables" as *),且确保该文件不含任何@mixin或样式规则 - 依赖
sass:math或sass:map等内置模块,也统一走@use "sass:map",不要混用@import
为什么 %placeholder 比 @mixin 更安全
占位符选择器天生不输出 CSS,只在 @extend 时按需注入,既避免样式膨胀,又杜绝“未调用却已污染”的风险。
-
@mixin reset { margin: 0; padding: 0; }被调用 10 次,就复制 10 次规则;而%reset { margin: 0; padding: 0; }+@extend %reset只生成一次 CSS -
%reset不能单独出现在 CSS 输出中,不会意外匹配到 HTML 里某个.reset类 - 跨文件使用
%placeholder必须先@use或@forward进当前作用域,天然受模块系统约束 - 禁止对插值选择器使用
%,例如.u-p-#{$n}里不能@extend %p-#{$n},Sass 会报错 "%placeholderis not a valid selector"
@forward 怎么精准控制模块透出内容
当你封装一个组件模块(如 _card.scss),又不想把内部实现细节(比如 $card-private-token)暴露给使用者,@forward 是唯一可控手段。
- 用
@forward "card" show $size-large, @mixin card-hover,下游只能访问这两个成员 - 用
@forward "card" hide $private-token,则除$private-token外全部透出 - 加
as card-前缀,如@forward "card" as card-,下游必须写card-$size-large,彻底切断命名耦合 - 切勿把所有东西塞进一个入口文件再
@forward全量透出——这等于变相回到@import的全局污染模式
最容易被忽略的一点:Sass 模块化只管编译时作用域,它不解决运行时类名冲突。如果最终 CSS 被打包进全局 scope(比如没配 CSS Modules 或 Shadow DOM),哪怕用了 @use,HTML 里仍可能因类名重复被覆盖。所以 @use 必须和构建工具链配合,比如 Webpack 的 css-loader 开启 modules,才能形成完整防护。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











