Note 1
@use & @import
在 SCSS 中,@use 和 @import 都是用于模块化管理的指令。
🧩 核心概念对比
| 特性 | @import | @use |
|---|---|---|
| 设计目标 | 传统的文件包含方式 | 现代模块系统 |
| 作用域 | 全局作用域 | 命名空间作用域 |
| 变量冲突 | 容易发生 | 避免冲突 |
| 成员可见性 | 所有成员全局可见 | 默认私有,可控制可见性 |
| 性能 | 多次导入会重复编译 | 模块只编译一次 |
| Sass 官方状态 | 逐步弃用 (deprecated) | 推荐使用 |
📚 语法对比
@import 语法
scss
// 导入文件
@import 'variables';
@import 'mixins';
// 使用导入内容(直接访问)
.element {
color: $primary-color;
@include flex-center;
}@use 语法
scss
// 导入文件并指定命名空间
@use 'variables' as vars;
@use 'mixins' as mx;
// 通过命名空间访问成员
.element {
color: vars.$primary-color;
@include mx.flex-center;
}🔍 关键区别详解
1. 作用域管理
@import:将所有导入内容放入全局作用域scss// colors.scss $primary: blue; // buttons.scss $primary: red; // 覆盖全局的 $primary // main.scss @import 'colors'; @import 'buttons'; // $primary 被覆盖为 red@use:使用命名空间隔离作用域scss@use 'colors' as c; @use 'buttons' as b; .header { background: c.$primary; // blue } .btn { background: b.$primary; // red }
2. 成员可见性控制
@import:所有成员完全公开@use:支持私有成员(以下划线_开头)scss// _utils.scss $_private-var: 10px; // 私有变量 $public-var: 20px; // 公共变量 // main.scss @use 'utils'; .box { margin: utils.$public-var; // ✅ 允许访问 padding: utils.$_private-var; // ❌ 报错:私有成员 }
3. 配置机制
@use支持模块配置:scss// _theme.scss $primary: blue !default; // 可配置的默认值 // main.scss @use 'theme' with ( $primary: red // 覆盖默认值 );
4. 成员访问方式
@import:直接访问所有成员@use:灵活的访问方式:scss// 默认命名空间(文件名) @use 'buttons'; .btn { background: buttons.$primary; } // 自定义命名空间 @use 'buttons' as b; .btn { background: b.$primary; } // 全局导入(慎用) @use 'colors' as *; .header { background: $primary; } // 直接访问
5. 性能优化
@import:每次导入都会重新编译文件@use:模块只编译一次,多次引用使用缓存文件结构: components/ _button.scss _card.scss main.scss // 使用 @use - 只编译一次 @use 'components/button'; @use 'components/card';
🚀 @use 的高级特性
1. 模块组合
scss
// _theme.scss
$primary: blue;
$secondary: green;
// _mixins.scss
@mixin box-shadow($color) {
box-shadow: 0 2px 4px rgba($color, 0.2);
}
// main.scss
@use 'theme';
@use 'mixins' with ($shadow-color: theme.$primary);
.card {
@include mixins.box-shadow;
}2. 与 @forward 配合使用
scss
// _library.scss
@forward 'theme';
@forward 'mixins';
@forward 'functions';
// main.scss
@use 'library' as lib;
.element {
color: lib.$primary;
@include lib.box-shadow;
}3. 元数据访问
scss
@use 'sass:meta';
// 检查模块是否存在
@if meta.module-variables('theme') {
@use 'theme';
}⚠️ 迁移注意事项
- 逐步替换:
scss
// 旧方式
@import 'variables';
@import 'mixins';
// 新方式
@use 'variables' as vars;
@use 'mixins' as mx;- 处理全局变量:
scss
// 创建全局访问点
// _globals.scss
@use 'variables' as *;
// 其他地方
@use 'globals' as *;- 第三方库兼容:
scss
// 对于不支持 @use 的库
@import '~legacy-library';📊 何时使用哪种方式
| 场景 | 推荐方式 |
|---|---|
| 新项目开发 | @use + @forward |
| 旧项目维护 | 逐步迁移到 @use |
| 简单项目/单文件 | @import (但不推荐) |
| 组件库开发 | @use + @forward |
| 需要严格作用域隔离 | @use |
💎 总结
@use 是 SCSS 模块化的未来,解决了 @import 的多个痛点:
- ✅ 避免全局命名冲突
- ✅ 提供更好的封装性
- ✅ 支持模块配置
- ✅ 提升编译性能
- ✅ 更清晰的依赖管理
虽然迁移需要一些工作,但 @use 提供了更健壮、可维护的样式架构,特别适合大型项目和组件库开发。官方已计划逐步淘汰 @import,因此建议新项目直接采用 @use 系统。
@forward & @use
在 Sass 中,@forward 和 @use 是模块系统(Module System)的核心功能,用于组织和管理样式代码。
@use:引入模块并使用其成员(变量、混合、函数等)@forward:转发模块的成员,使它们在当前文件被@use时可用(类似"中转站")
一、@forward 基础用法
scss
// src/_variables.scss
$primary: #3498db;
$secondary: #e74c3c;
// src/_mixins.scss
@mixin reset-list {
margin: 0;
padding: 0;
list-style: none;
}
// src/_index.scss (入口文件)
@forward 'variables'; // 转发变量
@forward 'mixins'; // 转发混合二、@forward + @use 搭配使用
场景:创建统一入口文件
scss
// styles.scss (主文件)
@use 'src/index' as *; // 引入入口文件并移除命名空间
body {
color: $primary; // 直接使用转发的变量
@include reset-list; // 直接使用转发的混合
}三、@forward 高级控制
1. 选择性转发成员
scss
// src/_index.scss
@forward 'variables' show $primary; // 只转发 $primary
@forward 'mixins' hide private-mixin; // 排除指定成员2. 添加前缀(避免命名冲突)
scss
// src/_index.scss
@forward 'variables' as var-*; // 添加前缀 var-
@forward 'mixins' as mix-*; // 添加前缀 mix-
// 使用方式
@use 'src/index';
body {
color: index.$var-primary; // 带前缀访问
@include index.mix-reset-list;
}3. 转发时配置默认值
scss
// src/_theme.scss (原始模块)
$theme-color: blue !default;
// src/_index.scss (入口)
@forward 'theme' with (
$theme-color: red // 覆盖默认值
);四、@use 与 @forward 关键区别
| 特性 | @use | @forward |
|---|---|---|
| 成员可见性 | 在当前文件可用 | 仅在文件被 @use 时暴露 |
| 命名空间 | 可自定义 (as <name>) | 支持前缀/后缀 |
| 配置默认值 | 支持 (with (...)) | 支持 (with (...)) |
| 成员过滤 | 不支持 | 支持 (show/hide) |
五、最佳实践示例
文件结构
styles/
├── utils/
│ ├── _variables.scss
│ ├── _mixins.scss
│ └── _index.scss # 统一入口
├── components/
│ └── _button.scss
└── main.scss步骤分解
- 入口文件 (
utils/_index.scss)
scss
// 转发 utils 下的所有工具
@forward 'variables';
@forward 'mixins';- 组件中使用 (
components/_button.scss)
scss
@use '../utils' as *; // 引入工具集
.button {
background: $primary;
@include rounded-corners;
}- 主文件 (
main.scss)
scss
@use 'utils'; // 工具集
@use 'components/button';
body {
font-family: utils.$font-stack;
}六、注意事项
- 避免循环转发:
A转发B,B又转发A会导致错误 - 作用域隔离:
@forward的文件无法直接使用转发的成员,需配合@use - 私有成员:以下划线 (
_) 开头的成员不会被转发 - 加载顺序:
Sass会自动处理依赖顺序,无需手动排序
通过合理使用 @forward 和 @use,可以构建出清晰、可维护的 Sass 模块化架构,特别适合大型项目。
私有成员(_ & -)
在 Sass 中,以下划线(_)开头的成员(变量、混合、函数等)具有特殊含义,它们被称为私有成员。以下是关键特性和使用规则:
一、核心特性
作用域限制:
- 以下划线开头的成员只能在定义它们的模块内部使用
- 外部文件通过
@use或@forward无法访问这些成员
命名规则:
scss// 私有成员示例 $_private-var: #ff0000; // 私有变量 @mixin _private-mixin { // 私有混合 /* ... */ } @function _private-fn() { // 私有函数 @return 10px; }
二、实际使用示例
scss
// _module.scss
$public-var: blue; // 公共变量
$_private-var: red; // 私有变量
@mixin public-mixin { // 公共混合
border: 1px solid $_private-var; // ✅ 内部可访问私有成员
}
@mixin _private-mixin { // 私有混合
/* ... */
}scss
// main.scss
@use 'module';
.element {
color: module.$public-var; // ✅ 正确访问公共成员
color: module.$_private-var; // ❌ 错误!无法访问私有变量
@include module.public-mixin; // ✅ 正确
@include module._private-mixin; // ❌ 错误!
}三、与 @forward 的交互
当使用 @forward 转发模块时:
- 私有成员不会被转发
- 在入口文件中不可访问
- 不会出现在转发的命名空间中
scss
// _library.scss
$_secret-color: #f00; // 私有变量
$public-color: #00f; // 公共变量
// _index.scss (入口文件)
@forward 'library';
// main.scss
@use 'index';
.test {
color: index.$public-color; // ✅ 正常访问
color: index.$_secret-color; // ❌ 编译错误:私有成员不可访问
}四、设计目的与最佳实践
封装实现细节:
scss// _grid.scss $_grid-columns: 12; // 内部计算使用 @function -column-width($cols) { // 私有函数 @return percentage($cols / $_grid-columns); } @mixin column($cols) { // 公共API width: -column-width($cols); }避免命名冲突:
scss// _theme.scss $_primary: #3498db; // 不会污染全局命名空间 // 公共接口 @function get-primary() { @return $_primary; }最佳实践:
- 所有不需要外部访问的成员都应添加下划线前缀
- 公共API保持无下划线命名
- 私有成员应紧跟在相关公共成员之后定义
五、特殊注意事项
文件私有 vs 模块私有:
- 下划线前缀使成员在模块级别私有
- 即使在同一目录的不同文件中也无法访问
连字符规则:
Sass同时支持_和-开头的私有成员
scss$-private-alternative: 10px; // 同样被视为私有与
@import的区别:- 传统
@import无法实现真正的私有化 - 模块系统 (
@use/@forward) 是实现私有的前提
- 传统
六、调试技巧
当遇到 "Private member" 错误时:
- 检查成员命名是否意外添加了下划线
- 确认是否应该通过公共API访问
- 使用
@debug在模块内部检查私有值:
scss
// _module.scss
@debug "Private value: #{$_private-var}"; // 内部调试通过合理使用下划线前缀,可以创建更健壮、可维护的 Sass 架构,有效隔离公共接口和内部实现。