SASS 模块

本文介绍 SASS 模块。

我们将介绍如何使用 @use@forward 实现 SASS 模块化,以及如何复用变量、混合宏、函数、主题设置和公共 API。

YouTube Video

SASS 模块

SASS 的模块系统可以清晰地限定样式的作用域,并提供易于复用和维护的设计。

模块的基本概念

SASS 模块解决了旧版 @import 出现的全局命名空间污染和依赖不明确的问题。每个文件作为模块加载,都拥有自己的命名空间,只有明确导出的内容可以被其他文件访问。

示例文件结构

首先,以下是一个实际项目结构的例子:。下面是一个小型设计系统的示例。

 1styles/
 2├─ _variables.scss
 3├─ _mixins.scss
 4├─ _functions.scss
 5├─ components/
 6│  ├─ _button.scss
 7│  └─ _card.scss
 8├─ utilities/
 9│  └─ _helpers.scss
10└─ main.scss
  • 这种结构不仅便于模块化,还便于测试与替换某些部分。
  • 片段文件的文件名前缀一般为下划线(_)。

@use的基础用法

@use用于加载模块并提供命名空间。这样可以避免命名冲突,并明确变量和函数的来源模块。

1// _variables.scss
2$primary-color: #0a74da;
3$padding-base: 12px;
  • 该文件只是简单地定义了一些变量。通过@use,可以直接引用模块公开的变量。
1// main.scss
2@use 'variables';
3
4.example {
5  color: variables.$primary-color;
6  padding: variables.$padding-base;
7}
  • 这里使用variables.命名空间来引用variables模块。这种方式可以清楚地了解每个变量或函数的来源。

命名空间简写与别名

使用as可以缩短命名空间。

1@use 'variables' as vars;
2
3.btn {
4  color: vars.$primary-color;
5}
  • 下面是使用vars作为variables模块简称的导入示例。根据你是更注重可读性还是输入的便捷性,选择合适的命名。

混合宏定义

mixin和函数也可以在模块内定义并使用。注释风格与项目规范一致,有助于提高代码清晰度。

1// _mixins.scss
2// Create a simple responsive container mixin
3@mixin container($max-width: 1200px) {
4  width: 100%;
5  margin-left: auto;
6  margin-right: auto;
7  max-width: $max-width;
8}
  • 此文件定义了一个容器的mixin。它可以接受参数并设置默认值。
1// main.scss
2@use 'mixins' as m;
3
4.wrapper {
5  @include m.container(1000px);
6}
  • 以下是用@include调用mixin的示例。

函数定义

函数用于返回值,并可在模块内定义和复用。通过将设计值的计算封装进函数,样式会更加稳定且易于维护。

1// _functions.scss
2@use 'sass:math';
3
4// Create a simple px-to-rem converter function
5@function to-rem($px, $base: 16) {
6  @return math.div($px, $base) * 1rem;
7}
  • 此文件定义了一个将像素值转换为 rem 的函数。还指定了一个默认基准值。
1// main.scss
2@use 'functions' as f;
3
4.title {
5  font-size: f.to-rem(24);
6}
  • 下面是通过 @use 调用函数并将结果应用于样式的示例。

模块导出与@forward(API设计)

如果需要对外公开多个内部文件,可以用@forward创建“公共API”。

1// _index.scss (module entry)
2@forward 'variables';
3@forward 'mixins';
4@forward 'functions';
  • 多个内部文件可以汇集在一个入口文件,通过该入口对外提供公共API。这样使用者只需导入这个入口文件即可访问所有需要的功能。
1// main.scss
2@use 'index' as ds; // ds = design system
3
4.button {
5  color: ds.$primary-color;
6  @include ds.container();
7}
  • variablesmixins的内容可以通过index一并访问。@forward使index成为公共层。

@forwardshow/hide选项控制API

如果只想公开特定变量,可以使用showhide选项。

1// _variables.scss
2$internal-thing: 10px !default; // for internal use
3$primary-color: #0a74da !default;
4$secondary-color: #f5f5f5 !default;
  • 使用!default可以让变量值支持被外部覆盖。
1// _index.scss
2@forward 'variables' show $primary-color, $secondary-color;
3@forward 'mixins';
  • 通过@forwardshow限定,可以只暴露必要的API元素。内部使用的变量和函数不会对外部可见。

让模块支持配置(使用with

如果模块中的变量使用了!default,则可以在导入时用with覆盖。

1// _theme.scss
2$brand-color: #ff6600 !default;
3$radius: 4px !default;
4
5@mixin button-style() {
6  background-color: $brand-color;
7  border-radius: $radius;
8}
  • !default定义默认值的模块,可以通过with来接受配置。
1// main.scss
2@use 'theme' with (
3  $brand-color: #2288ff,
4  $radius: 8px
5);
6
7.my-btn {
8  @include theme.button-style();
9}
  • @use ... with语法可在导入时覆盖模块中的默认变量。这对于主题切换非常有用。
  • 注意,with只在导入时生效,之后不能再修改这些值。

实用例子:按钮组件(完整示例)

下面我们试着用模块来设计按钮样式。首先,将变量和mixin分别放入单独的模块。

1// _variables.scss
2$btn-padding-y: 8px !default;
3$btn-padding-x: 16px !default;
4$btn-font-size: 14px !default;
5$btn-primary-bg: #0a74da !default;
6$btn-primary-color: #fff !default;
  • 这里定义了按钮的默认变量。使用!default可以让使用者自定义这些默认值。
 1// _mixins.scss
 2@use "variables" as v;
 3
 4@mixin btn-base() {
 5  display: inline-flex;
 6  align-items: center;
 7  justify-content: center;
 8  padding: v.$btn-padding-y v.$btn-padding-x;
 9  font-size: v.$btn-font-size;
10  border: none;
11  cursor: pointer;
12}
  • 这里定义了按钮的基础mixin。这样分离便于复用。
 1// _button.scss
 2@use 'variables' as v;
 3@use 'mixins' as m;
 4
 5.button {
 6  @include m.btn-base();
 7  background: v.$btn-primary-bg;
 8  color: v.$btn-primary-color;
 9  border-radius: 4px;
10  transition: opacity 0.15s ease;
11  &:hover { opacity: 0.9; }
12}
13
14.button--large {
15  padding: calc(v.$btn-padding-y * 1.5) calc(v.$btn-padding-x * 1.5);
16  font-size: v.$btn-font-size * 1.25;
17}
  • 按钮样式通过@use命名空间引用创建。有一个变体类,如.button--large
1// main.scss
2@use 'button'; // or @use 'index' that forwards button, variables, mixins
  • 只需导入button模块,即可直接应用按钮样式。

主题切换(使用多个主题文件)

主题切换可以通过with配置,也可以创建多个主题模块,根据需要用@use切换。

1// themes/_light.scss
2$brand-color: #0a74da !default;
1// themes/_dark.scss
2$brand-color: #111827 !default;
  • 可以在多个主题文件中定义品牌色等设置,在构建或导入时切换使用。
1// main.scss (light theme)
2@use 'theme' with ($brand-color: #0a74da);
3@use 'button';
  • 选择主题时,可以用with,也可以如@use 'themes/light'那样在构建时指定导入主题。

私有与公共(下划线前缀和!default

在 SASS 中,文件名开头加下划线会被标记为部分样式(partial)。但要管理模块导出可见性,建议用@forwardshowhide选项。

利用@forward可以整理公共API,隐藏内部实现。

实际项目中的最佳实践

以下是在实际使用 SASS 时非常有用的一些基本概念。这些准则都有助于减少开发中的混乱,保持代码结构清晰。

  • 如果变量可能因主题变化而改变,请加上!default。这样用户更容易覆盖其数值。
  • 模块应按责任进行划分,每个模块聚焦单一目标。通过将变量、混合宏、组件分离后,更便于管理。
  • 通过@forward管理公共内容,必要时结合showhide。严格定义公共内容范围有助于实现更安全的设计。
  • 通过命名空间,明确每个函数属于哪个模块。这样可以避免与其他代码混淆。
  • 请注意,with仅在@use时生效。因导入后不可再更改配置,请在导入时指定。
  • 文件名前加下划线,使其为片段文件,不会单独编译。这样更易于将文件组合成更大的结构。
  • index模块中包含用例有助于测试与文档说明。这样用户更容易理解其行为。

牢记这些要点,有助于管理大型项目,同时保持团队代码可读性。

总结

SASS 模块系统通过命名空间、公共 API 和简化的配置来组织样式代码。熟练使用@use@forward,能显著提升团队开发、主题切换和库设计的效率。

您可以在我们的YouTube频道上使用Visual Studio Code跟随上述文章进行学习。 请也查看我们的YouTube频道。

YouTube Video