本文章已经发布很久了,文章的内容可能已经失效或者部分失效,请酌情参考。

@use 的用法

我们在前面学习Partials的时候,已经讲过@use 的一部分用法了,它不仅可以导入sass 文件,也可以直接导入 css 文档。

@use 'test';
// 写.css后缀的话,明确表示导入的是纯 css 文件,
// 编译器不会去编译一些语句,如 @import 语句,而是原封不动地输出这条语句。
@use '../css/xxx.css'

后缀名可以省略的:

// 这是一样可以导入
@use 'test';
@use '../css/xxx'

后缀名省略后,在查找模块的时候,会自动查找:.scss.sass、目录下的_index.scss.css。比如:

@use 'test';

可以被引入的文件有:

  • test.scss
  • _test.scss
  • test.sass
  • _test.sass
  • test/_index.scss
  • test.css

当然,这些文件名不可以同时存在,否则会报错

典型使用

@use是Sass 3.10版本引入的模块化特性,它支持更好的命名空间和模块管理。推荐使用。它有以下几个优点:

  • @use 加载的样式表被称为模块(modules)。内置模块、自定义的css、scss文件都可以看成模块。
  • 私有命名空间@use 会创建了一个私有的命名空间,导入的变量、混入、函数以及其它样式只能通过命名空间访问。
  • 单次加载@use只会加载一次被引入的文件,不会重复加载,这有助于提高性能。
  • @use 一般要写在文件的开头,除了 @forward 和 变量的声明可以在他前面。
私有命名空间
/ 引入_test.scss 文件
@use 'test';

div {
  	// 使用的时候需要通过命名空间访问模块里面的变量
    color: test.$primary-color;
}
自定义命名空间名称

使用 @use ... as ... 语法来自定义命名空间名称:

// 导入模块的时候自定义命名空间
@use 'test' as A;
div {
  	// 使用新的命名空间名称
    color: A.$primary-color;
}
去除命名空间

使用 @use ... as * 语法来自定义命名空间名称:

@use 'test' as *;
div {
    // 在 _test.scss 模块中声明的变量直接当全局变量使用
    color: $primary-color;
}
模块中的私有成员

我们在编写模块中的代码的时候,如果某些mixins, functions, variables不想被其它模块使用,可以设置成私有的,只需将它们以 -_ 开头即可。

// _test.scss
$primary-color: #3498db;
// 私有成员
$_fs: 18px;
body {
    margin: 0;
    padding: 0;
}

我们在使用的时候,如果使用了其它模块的私有成员,则会报错。

@use 'test';
div {
    // $_fs 是私有成员,不能在其它模块中使用
    font-size: test.$_fs;
}
导入模块时传入配置

比如:我们可能在某个模块中定义变量的时候,使用了默认值标注,那么我们在导入这个模块的时候,是可以传入新的值去覆盖默认值的。使用 @use ... with () 语法去实现。

// _test.scss
// 设定了默认值
$color: red !default;
body {
    background-color: $color;
}

我们导入的时候传入新值去覆盖:

// 导入的时候传入新值,可以传多个
@use 'test' with ($color: 'blue');
div {
    background-color: test.$color;
}

生成的 css 代码:

body {
  background-color: "blue";
}
div {
  background-color: "blue";
}

@forward 的用法

@forward 的作用是转发模块的成员,而不是引入成员到当前文件使用,也就是说,通过 @forward 加载一个模块的成员,这些成员并不能在当前文件内访问,而仅仅是将这些成员当作自己的成员对外暴露出去。

@forward@use 在导入模块的方式上是一样的,不过作用不一样。下面我们举例说明,我们创建三个文件:

  • _test.scss:我们将变量声明放在这里面

    // 声明变量
    $color: red;
    $fontSize: 20px;
    // 普通的代码
    body {
        background-color: green;
    }
    
  • x1.scss:我们使用 @forward 引入 _test.scss 模块

    @forward 'test';
    
    .xx {
        // 使用@forward引入的模块中的成员,不能在当前模块中使用
        // color: test.$color;
    }
    
  • x2.scss:我们使用 @use 引入 _x1.scss 模块

    @use 'x1';
    
    div {
      	// x1.scss 中使用 @forward 引入的变量等信息,虽然他自己不能用
      	// 但它中转了一下并暴露出去,其它模块可以通过它使用
        color: x1.$color;
      	font-size: x1.$fontSize;
    }
    
转发时的成员可见性控制

选择转发:

@forward 默认会将它引入的模块中的所有变量、mixin 等都转发出去。如果只想部分转发可以使用:

@forward '模块' show 要转发的成员1,要转发的成员2,…… ;

使用例子:

// 只将 test 模块中的 $color, $fontSize 转发出去
@forward 'test' show $color, $fontSize;
// 只将 test 模块中的 $color 转发出去
@forward 'test' show $color

选择不转发:

// 将 test 模块中除$fontSize成员外的其它成员转发
// 也就是不转发 $fontSize
@forward 'test' hide $fontSize;
转发时添加前缀

如果在一个文件中转发多个文件中的成员,在使用时可能会存在多个文件中的成员同名,这样会导致编译出现错误。为了解决这个问题,我们可以在转发的时候给他们添加不同的前缀。

// x1.scss
// 我们可以转发的时候使用as加前缀,这里加了个 abc- 前缀。 *别忘了。
@forward 'test' as abc-*;

我们使用的时候,需要在成员名前面要加上前缀:

@use 'x1';
div {
  	// 加上 abc- 前缀
    color: x1.$abc-color;
}

注意:当“添加前缀”和“成员可见性控制”同时使用的时候,注意也一并加上前缀:

// 别忘了“成员可见性控制”时也要加前缀
@forward 'test' as abc-* show $abc-color;