真正可复用的动画库必须分离关键帧定义与调用逻辑:统一在 _animations.scss 中用带项目前缀的静态名(如 @keyframes my-fade-in)定义关键帧,仅使用 transform 和 opacity,通过 @use 引入;每个动画配同名 @mixin(如 @mixin fade-in),参数仅控制调用行为($duration、$easing 等),不侵入关键帧内容;多段动画用 @include keyframes-template 手动编写帧,杜绝动态拼接名称或顶层循环生成 @keyframes。

直接在组件里写 @keyframes,等于把动画逻辑焊死在局部——改个缓动函数就得全局搜、逐个修,还容易触发重排、掉帧。真正可复用的动画库,必须把关键帧定义和调用逻辑彻底分离。
每个动画配一个固定、带前缀的 @keyframes 名
Sass 不支持在 @include 里动态生成隔离的作用域级关键帧名,所有 @keyframes 编译后都挂在 CSS 全局作用域。拼字符串(比如 fade-in-#{$duration}-#{$easing})看似灵活,实则极易冲突,CI 流程里 grep 一跑全是隐患。
- 统一在
_animations.scss中定义,名称带项目前缀,如@keyframes my-fade-in - 避免用
@import加载该文件——它会污染全局命名空间;改用@use 'animations' as anim - 关键帧内部只用
transform和opacity:这两类属性走合成层,不触发重排重绘 - 别硬编码数值,用 SCSS 变量驱动,比如
$anim-fade-duration: 0.3s,后续批量调整才可控
用 @mixin 封装调用接口,而非整条 animation 值
写 @mixin anim($value) { animation: $value; } 是最常见也最危险的偷懒方式——它断掉了对关键帧内容的控制权。一旦要微调起始缩放值或填充模式,就得重写整个 @keyframes,复用性归零。
- 每个动画对应一个同名
@mixin,如@mixin fade-in - 参数只控制调用行为:
$duration、$easing、$fill、$delay,不碰关键帧定义本身 - 示例:
@mixin fade-in($duration: 0.3s, $easing: ease-out, $fill: forwards) { animation: my-fade-in $duration $easing $fill; } - 调用时只需
@include fade-in(0.4s, cubic-bezier(0.2, 0.8, 0.4, 1));,干净、明确、无副作用
多段关键帧动画别强求“全自动”
需要 0% → 50% → 100% 三段位移?别用 @each 循环生成帧——Sass 编译期无法保证帧顺序,且 CSS 标准要求关键帧名必须是静态字符串,顶层循环会直接报错。
- 放弃“动态插值多帧”的幻想,改用「模板 mixin + 手动帧内容」结构
- 写一个包裹型
@mixin keyframes-template($name) { @keyframes #{$name} { @content; } } - 具体帧写在调用处:
@include keyframes-template('my-skeleton-scan') { 0% { background-position: -100% 0; } 100% { background-position: 200% 0; } } - 高频组合(如呼吸、闪烁)可单独封装小 mixin,在
@content里调用,但不要拆成多个@content块
真正难的不是写几个 @mixin,而是守住那条线:关键帧名必须静态、语义化、带前缀;调用逻辑必须参数化、可预测、不侵入关键帧定义。一旦开始拼接名字、传整条 animation 值、或在顶层循环生成 @keyframes,维护成本就指数级上升——而且浏览器根本不会帮你加速。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











