variable-exists()仅检测变量是否声明,无法识别null/空值;应配合meta.type-of($var) != 'null'判断有效值,或用map-has-key()处理配置map。

variable-exists() 只能告诉你变量“有没有被声明过”,不能判断它是不是 null、空字符串或 false —— 想靠它做样式开关,大概率会漏掉未赋值的变量,导致本该跳过的 CSS 还是生成了。
variable-exists() 的真实行为:声明 ≠ 有值
SCSS 编译时,variable-exists() 检查的是符号表里是否存在该变量名,不管它是否被赋过值。比如:
@if variable-exists(border-radius) {
.box { border-radius: $border-radius; }
}
只要你在某处写过 $border-radius:(哪怕后面没跟值,或者写了 $border-radius: null;),这个 @if 就为 true,.box 规则就会输出 —— 即使最终 $border-radius 是 null,编译后也会变成 border-radius: null;,浏览器直接忽略,但代码体积和可维护性已受损。
- ✅ 正确用法场景:检查第三方库是否导出了某个配置变量(如
$bootstrap-breakpoints) - ❌ 错误用法场景:用来控制“如果用户没配
$shadow,就不生成 box-shadow” - ⚠️ 注意:
global-variable-exists()和variable-exists()行为一致,只是作用域不同;局部变量用前者会返回 false
真正判断“有没有有效值”得用 meta.type-of()
要区分“声明了但没赋值”和“声明了且有实际值”,必须配合 meta.type-of() 判断类型。SCSS 中未赋值的变量、显式设为 null 的变量,其类型都是 'null'。
@if meta.type-of($shadow) != 'null' {
.card { box-shadow: $shadow; }
}
这样才可靠。常见组合判断还有:
-
meta.type-of($color) == 'color'→ 确保是颜色值,避免传入字符串"#fff"却当变量用 -
not (meta.type-of($size) == 'null')→ 等价于“有定义且非 null” -
str-length($font-family) > 0→ 针对字符串变量,排除空值""
map-has-key() 才是配置驱动开发的主力
实际项目中,配置往往存在 map 里(比如 $theme: (primary: #1890ff, radius: 4px)),这时 variable-exists() 完全无用 —— 它不查 map 内部。
正确姿势是先用 map-has-key() 检查 key 是否存在,再用 map-get() 安全取值:
$theme: (primary: #1890ff);
@if map-has-key($theme, radius) {
.btn {
border-radius: map-get($theme, radius);
}
}
- ✅
map-has-key()返回布尔值,可直接用于@if - ⚠️
map-get($theme, radius)在 key 不存在时返回null,所以不能单独依赖它做判断 - ❌ 不要用
@if $theme.radius—— SCSS 不支持点号访问 map,会报错Invalid CSS after "$theme": expected expression
@extend 不能条件化,改用 @mixin + @if 组合
有人想这么写:
@if variable-exists(use-reset) {
.btn { @extend %reset; }
}
不行。@extend 不支持在 @if 块内动态触发,编译会报 Extend directives may only be used within rules.。
替代方案是把逻辑封装进 @mixin:
@mixin btn-base {
@if variable-exists(use-reset) and meta.type-of($use-reset) != 'null' {
@extend %reset;
}
padding: 8px 16px;
}
.btn { @include btn-base; }
- ✅
@mixin内部可自由使用@if+ 各类 introspection 函数 - ⚠️ 注意:扩展目标(如
%reset)必须在@include前已定义,否则报Undefined extend - ? 复杂逻辑建议拆到
_functions.scss里,用函数返回布尔值,让 mixin 更干净
最常被忽略的一点:所有这些判断都发生在编译期,一旦 CSS 输出,就再无回旋余地。别指望用 variable-exists() 去响应运行时主题切换 —— 那是 CSS 自定义属性 + @property 或 JS 的事。SCSS 的“条件”,只管构建那一刻你手里的变量快照长什么样。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











