使用 @use

最简单的 `@use` 规则写成 `@use ""`,它在给定的 URL 加载模块。 以这种方式加载的任何样式都将在编译后的 CSS 输出中只包含一次,无论这些样式被加载了多少次。

Compatibility: Dart Sass since 1.23.0 | LibSass ✗ | Ruby Sass ✗

目前只有 Dart Sass 支持@use。 其他实现的用户必须改用@import 规则。

@use 规则加载 mixinsfunctionsvariables 来自其他 Sass 样式表,并将来自多个样式表的 CSS 组合在一起。 由@use加载的样式表称为modules。 Sass 还提供了充满实用功能的内置模块

最简单的 @use 规则写成 @use "<url>",它在给定的 URL 加载模块。 以这种方式加载的任何样式都将在编译后的 CSS 输出中只包含一次,无论这些样式被加载了多少次。

⚠️ 注意!
样式表的“@use”规则必须位于“@forward”以外的任何规则之前,包括样式规则。 但是,您可以在“@use”规则之前声明变量,以便在 配置模块 时使用。

scss
Scss
scss
// foundation/_code.scss
code {
  padding: .25em;
  line-height: 0;
}
// foundation/_lists.scss
ul, ol {
  text-align: left;

  & & {
    padding: {
      bottom: 0;
      left: 0;
    }
  }
}
// style.scss
@use 'foundation/code';
@use 'foundation/lists';

加载成员

您可以通过编写<namespace>.<variable><namespace>.<function>()@include <namespace>.<mixin>() 从另一个模块访问变量、函数和混合宏 . 默认情况下,命名空间只是模块 URL 的最后一个组成部分。

使用@use加载的成员(变量、函数和混合)仅在加载它们的样式表中可见。 如果其他样式表也想访问它们,则需要编写自己的“@use”规则。 这有助于轻松找出每个成员的确切来源。 如果您想一次从多个文件中加载成员,您可以使用 @forward 规则 从一个共享文件中全部转发它们。

💡 有趣的事实:

因为 @use 将命名空间添加到成员名称中,所以在编写样式表时选择非常简单的名称(如 $radius$width)是安全的。 这与旧的 @import 规则 不同,它鼓励用户编写长名称,如 $mat-corner-radius 以避免与其他库发生冲突,并且 它有助于使您的样式表清晰易读!

scss
Scss
scss
// src/_corners.scss
$radius: 3px;

@mixin rounded {
  border-radius: $radius;
}
// style.scss
@use "src/corners";

.button {
  @include corners.rounded;
  padding: 5px + corners.$radius;
}

选择命名空间

默认情况下,模块的命名空间只是其 URL 的最后一个组成部分,没有文件扩展名。 但是,有时您可能希望选择不同的命名空间——您可能希望对经常引用的模块使用较短的名称,或者您可能正在加载具有相同文件名的多个模块。 您可以通过编写@use "<url>" as <namespace> 来做到这一点。

scss
Scss
scss
// src/_corners.scss
$radius: 3px;

@mixin rounded {
  border-radius: $radius;
}
// style.scss
@use "src/corners" as c;

.button {
  @include c.rounded;
  padding: 5px + c.$radius;
}

您甚至可以通过编写 @use <url> as * 来加载 without 命名空间的模块。 不过,我们建议您只对您编写的样式表执行此操作; 否则,他们可能会引入导致名称冲突的新成员!

scss
Scss
scss
// src/_corners.scss
$radius: 3px;

@mixin rounded {
  border-radius: $radius;
}
// style.scss
@use "src/corners" as *;

.button {
  @include rounded;
  padding: 5px + $radius;
}

私人会员

作为样式表作者,您可能不希望您定义的所有成员都可以在样式表之外使用。 Sass 以 -_ 开头的名称可以轻松定义私有成员。 这些成员将在定义它们的样式表中正常工作,但它们不会成为模块公共 API 的一部分。 这意味着加载模块的样式表看不到它们!

💡 有趣的事实:
如果你想让一个成员对整个 package 私有,而不仅仅是一个模块,只是不要从你的包的任何入口点(你的样式表)转发它的模块 告诉您的用户加载以使用您的包)。 您甚至可以 隐藏该成员,同时转发其模块的其余部分!

scss
Scss
scss
// src/_corners.scss
$-radius: 3px;

@mixin rounded {
  border-radius: $-radius;
}
// style.scss
@use "src/corners";

.button {
  @include corners.rounded;

  // This is an error! $-radius isn't visible outside of `_corners.scss`.
  padding: 5px + corners.$-radius;
}

配置

样式表可以使用 !default 标志 定义变量,使它们可配置。 要使用配置加载模块,请编写@use <url> with (<variable>: <value>, <variable>: <value>)。 配置的值将覆盖变量的默认值。

scss
Scss
scss
// _library.scss
$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;
}
// style.scss
@use 'library' with (
  $black: #222,
  $border-radius: 0.1rem
);

使用 Mixins

使用@use ... with配置模块非常方便,尤其是在使用最初编写用于使用 “@import”规则 的库时。 但它不是特别灵活,我们不建议将其用于更高级的用例。 如果您发现自己想要一次配置多个变量,将 maps 作为配置传递,或者在加载模块后更新配置,请考虑编写一个 mixin 来设置您的变量,然后再编写另一个 mixin 来注入你的样式。

scss
Scss
scss
// _library.scss
$-black: #000;
$-border-radius: 0.25rem;
$-box-shadow: null;

/// If the user has configured `$-box-shadow`, returns their configured value.
/// Otherwise returns a value derived from `$-black`.
@function -box-shadow() {
  @return $-box-shadow or (0 0.5rem 1rem rgba($-black, 0.15));
}

@mixin configure($black: null, $border-radius: null, $box-shadow: null) {
  @if $black {
    $-black: $black !global;
  }
  @if $border-radius {
    $-border-radius: $border-radius !global;
  }
  @if $box-shadow {
    $-box-shadow: $box-shadow !global;
  }
}

@mixin styles {
  code {
    border-radius: $-border-radius;
    box-shadow: -box-shadow();
  }
}
// style.scss
@use 'library';

@include library.configure(
  $black: #222,
  $border-radius: 0.1rem
);

@include library.styles;

重新分配变量

加载模块后,您可以重新分配其变量。

scss
Scss
scss
// _library.scss
$color: red;
// _override.scss
@use 'library';
library.$color: blue;
// style.scss
@use 'library';
@use 'override';
@debug library.$color;  //=> blue

如果您使用 as * 导入没有命名空间的模块,这甚至会起作用。 分配给该模块中定义的变量名称将覆盖其在该模块中的值。

⚠️ 注意!

无法重新分配内置模块变量(例如 math.$pi)。

查找模块

为您加载的每个样式表写出绝对 URL 不会有任何乐趣,因此 Sass 用于查找模块的算法使其更容易一些。 对于初学者,您不必明确写出要加载的文件的扩展名; @use "variables" 将自动加载 variables.scssvariables.sassvariables.css

⚠️ 注意!

为了确保样式表适用于每个操作系统,Sass 通过_URL_ 加载文件,而不是通过_文件路径_。 这意味着您需要使用正斜杠,而不是反斜杠,即使在 Windows 上也是如此。

加载路径

所有 Sass 实现都允许用户提供_加载路径_:Sass 在定位模块时将查找的文件系统路径。 例如,如果您将 node_modules/susy/sass 作为加载路径传递,则可以使用 @use "susy" 加载 node_modules/susy/sass/susy.scss

不过,模块将始终相对于当前文件首先加载。 只有在不存在与模块 URL 匹配的相关文件时才会使用加载路径。 这可确保您在添加新库时不会不小心弄乱您的相关导入。

💡 有趣的事实:

与其他一些语言不同,Sass 不要求您使用 ./ 进行相对导入。 相对导入始终可用。

部分

按照惯例,仅作为模块加载而不是自行编译的 Sass 文件以“_”开头(如“_code.scss”)。 这些称为 partials,它们告诉 Sass 工具不要尝试自行编译这些文件。 导入部分时,您可以省略 _

索引文件

如果您在文件夹中写入 _index.scss_index.sass,当您加载文件夹本身的 URL 时,索引文件将自动加载。

scss
Scss
scss
// foundation/_code.scss
code {
  padding: .25em;
  line-height: 0;
}
// foundation/_lists.scss
ul, ol {
  text-align: left;

  & & {
    padding: {
      bottom: 0;
      left: 0;
    }
  }
}
// foundation/_index.scss
@use 'code';
@use 'lists';
// style.scss
@use 'foundation';

加载 CSS

除了加载 .sass 和 .scss 文件外,Sass 还可以加载普通的旧 .css 文件。

scss
Scss
scss
// code.css
code {
  padding: .25em;
  line-height: 0;
}
// style.scss
@use 'code';

作为模块加载的 CSS 文件不允许任何特殊的 Sass 功能,因此不能公开任何 Sass 变量、函数或混合。 为了确保作者不会不小心在他们的 CSS 中编写 Sass,所有不是有效 CSS 的 Sass 功能都会产生错误。 否则,CSS 将按原样呈现。 它甚至可以 扩展

@import 的区别

@use 规则旨在取代旧的 @import 规则,但它有意设计为以不同的方式工作。 以下是两者之间的一些主要区别:

  • @use 仅使变量、函数和混合在当前文件的范围内可用。 它从不将它们添加到全局范围。 这可以很容易地找出您的 Sass 文件引用的每个名称的来源,并且意味着您可以使用较短的名称而没有任何冲突风险。
  • @use 只加载每个文件一次。 这确保您不会意外地多次重复依赖项的 CSS。
  • @use 必须出现在文件的开头,并且不能嵌套在样式规则中。
  • 每个 @use 规则只能有一个 URL。
  • @use 需要在其 URL 周围加上引号,即使在使用 缩进语法 时也是如此。