SASS/SCSS如何从局部文件动态访问属性/方法?
解决Sass中通过@use引入模块后动态获取变量的问题
问题背景
现有Sass局部文件_colors.scss:
// _colors.scss $foo: red;
通过@use引入到test.scss中可正常直接使用变量:
// test.scss @use './colors'; .test { color: colors.$foo; }
但尝试在mixin中通过参数动态获取模块内变量时,几种写法均无法得到预期结果:
// test.scss @use './colors'; @mixin getColor($type) { // 无效写法:模拟JS数组访问,Sass不支持 color: colors[$type]; // 无效写法:插值仅做文本替换,不会解析变量 color: #{colors.{$type}; // 无效写法:同上,仅输出文本 color: colors.#{$type}; } .test { @include getColor(foo); }
可行实现方案
方案1:将变量转为映射(Map)管理
修改_colors.scss,把需要动态访问的变量整合到一个映射中,也可以保留原变量不影响其他使用:
// _colors.scss $foo: red; // 定义颜色映射,统一管理需动态访问的变量 $color-map: ( foo: $foo );
在test.scss中使用map-get函数从映射中动态取值:
// test.scss @use './colors'; @mixin getColor($type) { color: map-get(colors.$color-map, $type); } .test { @include getColor(foo); // 编译后输出 color: red; }
方案2:使用Sass内置meta.get-variable函数(Sass 3.7+)
如果不想修改原有_colors.scss的结构,可借助Sass核心库的meta模块提供的get-variable函数,直接从模块中动态获取变量:
// test.scss @use './colors'; @use 'sass:meta'; @mixin getColor($type) { // 第二个参数为模块名,即@use时指定的命名空间(默认是文件名) color: meta.get-variable($type, colors); } .test { // 注意:这里传入的是变量名(不带$),可以直接传标识符或字符串 @include getColor(foo); // 或传字符串形式 // @include getColor('foo'); }
原写法无效原因
Sass的@use模块系统是静态编译的,字符串插值(#{})仅在生成最终CSS时做文本替换,不会在Sass编译阶段解析模块内的变量引用。因此colors.#{$type}这类写法最终只会输出colors.foo的文本内容,而不会解析为对应的变量值red。
内容的提问来源于stack exchange,提问作者R2rito
相关产品推荐
相关产品推荐

