配合 @use 使用的规则
因为 @use 引入的模块只能在当前文件内使用,所以说如果要组合多个模块作为一个新模块暴露出去,是行不通的
@forward 正是为此而生
@forward 会加载 Sass 样式表,并让其混入(mixin)、函数(function)和变量在当别的样式表使用 @use 引入当前样式表时能够被使用。它使跨多个文件组织 Sass 库成为可能,用户可以加载单个入口文件。
基本使用
基础语法为 @forward "<url>"。它与 @use 一样通过 URL 来加载模块,但它让使用该模块的用户能够使用已加模块的公共成员,就像这些已加载模块的公共成员定义在了该模块内一样。
被 @forward 引入的模块在当前文件中是不可用的(仅仅是字面意思的转发),如果需要使用,还需要编写 @use 规则。不用担心,它只会被加载一次!
如果同时使用 @forward 和 @use 引入一个文件,先写 @forward 总是没错的。这样的话,用户就可以被转发的模块;反之,如果先写 @use,用户就不能配置被转发的模块(会报错)。
在处理模块中的 CSS 样式时,@forward 与 @use 并无差别。来自被转发模块的样式会包含在输出的 CSS 中,并且在只有 @forward 的却无 @use 模块中,被转发模块的样式可以被继承(@extend)。
1 2 3 4 5 6
| @mixin list-reset { margin: 0; padding: 0; list-style: none; }
|
1 2 3 4 5 6
| @use 'bootstrap';
li { @include bootstrap.list-reset; }
|
1 2 3 4 5
| li { margin: 0; padding: 0; list-style: none; }
|
添加前缀
在模块中的成员,因为有了命名空间这一特性,通常名称都非常简单易懂。但是这些名称在其模块外部可能并无意义,所以 @forward 能够在转发的模块前加上额外的前缀。
格式为 @forward "<url>" as <prefix>-*,它会在每个混入(mixin)、函数(function)和变量的名称前加上前缀。例如在某个模块中有一个成员叫 reset,它被转发后 as list-*,那么在外部需通过 list-reset 来使用。
1 2 3 4 5 6
| @mixin reset { margin: 0; padding: 0; list-style: none; }
|
1 2
| @forward 'src/list' as list-*;
|
1 2 3 4 5 6
| @use 'bootstrap';
li { @include bootstrap.list-reset; }
|
1 2 3 4 5
| li { margin: 0; padding: 0; list-style: none; }
|
可见性
有时候你不希望转发模块中所有成员。你希望有些成员变量是私有的,只在你的包内才能使用;又或者你希望用户用不同的方法加载某些成员。你可以通过 @forward "<url>" hide <members...> 或者 @forward "<url>" show <members...> 来精准控制哪些成员能够转发。
hide 隐藏意味着不应该转发列表中的成员,其余成员都应正常转发。show 意味着只转发列表中指定的成员。在列表中可以列出混入(mixin)、函数(function)和变量(要带上$)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| $horizontal-list-gap: 2em;
@mixin list-reset { margin: 0; padding: 0; list-style: none; }
@mixin list-horizontal { @include list-reset;
li { display: inline-block; margin: { left: -2px; right: $horizontal-list-gap; } } }
|
1 2
| @forward 'src/list' hide list-reset, $horizontal-list-gap;
|
配置模块
与 @use 的配置方法几乎一致,唯一区别是 @forward 配置中的值可以使用 flag !default。这样在允许模块修改上游值的同时,下游也能覆盖该默认值。
1 2 3 4 5 6 7 8 9
| $black: #000 !default; $border-radius: 0.25rem !default; $box-shadow: 0 0.5rem 1rem rgba($black, 0.15) !default;
code { border-radius: $border-radius; box-shadow: $box-shadow; }
|
1 2 3 4 5
| @forward 'library' with ( $black: #222 !default, // 覆盖了 library 的值 $border-radius: 0.1rem !default );
|
1 2 3 4
| @use 'opinionated' with ( $black: #333 // 覆盖了 opinionated 的值 );
|
1 2 3 4
| code { border-radius: 0.1rem; box-shadow: 0 0.5rem 1rem rgba(51, 51, 51, 0.15); }
|