加载指示器变量必须集中定义在顶层,如\_variables.scss或\_loaders.scss中,且须在任何@import或@use前声明;局部定义会导致跨组件复用失效、主题切换失控,正确做法是配合!default、currentColor和@mixin封装实现统一控制与自动适配。

加载指示器变量必须集中定义在顶层
不能把 $loader-size、$loader-color 这类变量写在组件 SCSS 文件内部,否则跨组件复用或主题切换时无法统一控制。所有加载器相关变量应放在项目级 _variables.scss 或专用 _loaders.scss 中,且必须在任何 @import 或 @use 加载器样式前声明。
常见错误是边写边定义:$loader-color: #007bff; 放在 .spinner 规则块里——这会让它只在该块内有效,后续 @include spinner-ring() 就取不到值。
- 推荐结构:
$loader-size: 24px !default;(带!default允许上层覆盖) -
$loader-color: currentColor !default;(默认继承文字色,适配深色/浅色主题) -
$loader-speed: 0.6s !default;(避免硬编码动画时长)
用 @mixin 封装不同形态的加载器,而非重复写 keyframes
直接在每个组件里手写 @keyframes spin + animation: spin 0.6s infinite linear 是反模式。Sass 不支持动态生成 @keyframes 名,但可以封装参数化调用逻辑。
正确做法是在 _loaders.scss 中定义固定名关键帧,再用 @mixin 控制行为:
立即学习“前端免费学习笔记(深入)”;
@keyframes loader-spin {
to { transform: rotate(360deg); }
}
@mixin spinner-ring($size: $loader-size, $color: $loader-color, $speed: $loader-speed) {
display: inline-block;
width: $size;
height: $size;
border: 2px solid rgba($color, 0.3);
border-top-color: $color;
animation: loader-spin $speed infinite linear;
}
调用时只需:.loading { @include spinner-ring(28px, #ff6b6b); },无需关心关键帧细节。
- 不要写
@mixin anim($val) { animation: $val; }—— 它切断了对关键帧内容和 timing function 的控制 - 所有
@keyframes必须加项目前缀(如my-loader-spin),防止第三方库冲突 - 若需多色环效果,另建
@mixin spinner-dots(),复用同一组变量,不新增关键帧
配合 currentColor 和主题变量实现自动适配
加载器颜色不应写死为 #007bff,而应默认绑定到当前上下文文字色或主题主色。这样按钮内嵌加载器、深色模式弹窗中的加载器会自动匹配背景与文字对比度。
示例:
// 在主题配置中
$themes: (
light: (loader-color: #007bff),
dark: (loader-color: #4f46e5)
);
// 加载器 mixin 内部
border-top-color: theme-value("loader-color");
- 避免用
map-get($theme-map, "loader-color")直接取值 ——theme-value()函数已封装好容错逻辑 - 若组件强制指定颜色(如警告态加载器),允许传参覆盖:
@include spinner-ring($color: #ef4444) - 注意:CSS 动画中
border-color无法用transition平滑变化,所以主题切换时加载器会突变,这是正常表现
编译时确保 loader 模块被正确引入且顺序无误
很多项目加载器样式不生效,根本原因是构建链中 @import 或 @use 顺序错了。SCSS 变量作用域是“自上而下”,@use 导入的模块变量不会自动提升到全局。
典型错误写法:
@use 'loaders'; // ❌ 此时 $loader-size 还未声明
.spinner { @include loaders.spinner-ring(); }
$loader-size: 32px; // 太晚了
正确顺序:
$loader-size: 32px;
$loader-color: #4f46e5;
@use 'loaders';
.spinner { @include loaders.spinner-ring(); }
- Webpack/Vite 用户:确认
sass-loader或dart-sass版本 ≥ 1.70,旧版本对@use变量透传支持不完整 - 别用
@import "loaders"混合@use—— 模块系统不兼容,@use下的变量无法被@import文件访问 - 如果 loader 样式要用于 Vue/React 组件 scoped style,必须把
@include放在非 scoped 的全局样式中,或改用 CSS-in-JS 方案
transform 和 opacity,纯 rotate() 在某些 Android WebView 中仍会触发重排。上线前务必在真机上验证 will-change: transform 是否已加,以及是否启用了硬件加速。


















