前端 er 速码!TinyVue 全局动效实践指南,干货拉满
本文由TinyVue贡献者程锴原创。
一、前言:为什么要统一管理动效
在前端开发中,动画不仅是锦上添花的“视觉糖”,更是交互体验的重要组成部分: 它能引导用户关注、反馈操作结果、缓解等待焦虑、提升产品质感。
但当项目变大、组件增多后,你可能遇到这些问题:
- 同样的淡入淡出,在不同组件中表现不一致
- 想调整动画速度,却要修改多个文件
- 动画样式难以复用、维护困难
这些问题的根源在于:动画定义分散、缺乏统一管理。 为此,TinyVue 引入了一套全新的 全局动效体系,基于 LESS + CSS 变量 实现集中配置与动态控制。
二、为什么选择 LESS + CSS 变量
常见的动画实现方式有两种:
| 方式 | 优点 | 缺点 |
|---|---|---|
1️⃣ 直接在组件中定义@keyframes
|
简单直观,局部可定制 | 无法统一、修改麻烦 |
| 2️⃣ 全局管理动画 | 可复用、风格一致 | 静态,难以动态调整 |
TinyVue 采用 LESS + CSS 变量结合方案,兼顾两者优势:
✅ 变量化控制 所有动效的时长、透明度、位移量都由 CSS 变量控制
✅ 可局部覆盖 组件可根据需求覆盖变量,灵活调整动画参数
✅ 主题可切换 只需在不同主题文件中修改变量,即可快速切换全局动效风格
三、环境搭建与示例预览
1. 拉取 TinyVue 仓库:
git clone https://github.com/opentiny/tiny-vue.git
cd tiny-vue
pnpm i
2. 启动TinyVue项目
pnpm dev
浏览器访问:http://localhost:7130
3. 打开配置文件:
/packages/theme/src/base/vars.less
1). 修改变量即可实时生效:
--tv-motion-slide-speed: 1.2s;
刷新页面后,可在抽屉(Drawer)组件中观察滑动动效速度变化。
同样地:
--tv-motion-fade-offset-y: 100px;
会影响对话框(DialogBox)的淡入位移动画。
四、全局动效的设计思路
1. 统一变量管理
所有动画相关参数集中在 /packages/theme/src/base/vars.less:
:root {
/* 淡入淡出 */
--tv-motion-fade-speed: 0.3s;
/* 滑动类 */
--tv-motion-slide-speed: 0.4s;
--tv-motion-slide-offset-left: -30px;
--tv-motion-slide-offset-left-mid: -10px;
--tv-motion-slide-opacity-mid: 0.5;
/* 蚂蚁线 */
--tv-motion-ants-shift: 8px;
--tv-motion-ants-speed: 0.8s;
}
修改任意变量即可影响全局动效表现。
2. 按类型分类管理
为方便维护和扩展,动效按类型拆分为多个 LESS 文件:
motion/
fade.less // 淡入淡出
slide.less // 滑动
zoom.less // 缩放
rotate.less // 旋转
bounce.less // 弹跳
ants.less // 蚂蚁线
...
index.less // 汇总引入
每个文件独立维护一类动效,结构清晰,修改成本低。
3. 动效命名规范
统一命名规则:
{type}-{direction}-{state}
示例:
-
fade-in:淡入 -
slide-left-in:从左滑入 -
zoom-in:放大进入 -
ants-x-rev:蚂蚁线反向滚动
保证语义清晰、全局唯一,方便引用与调试。
五、动效实现示例
1️⃣ 淡入淡出动效
@keyframes fade-in {
0% { opacity: 0; }
100% { opacity: 1; }
}
@keyframes fade-out {
0% { opacity: 1; }
100% { opacity: 0; }
}
调用方式:
.fade-enter-active {
animation: fade-in var(--tv-motion-fade-speed) ease-out both;
}
.fade-leave-active {
animation: fade-out var(--tv-motion-fade-speed) ease-in both;
}
2️⃣ 滑动动效
@keyframes slide-left-in {
0% {
opacity: 0;
transform: translateX(var(--tv-motion-slide-offset-left));
}
50% {
opacity: var(--tv-motion-slide-opacity-mid);
transform: translateX(var(--tv-motion-slide-offset-left-mid));
}
100% {
opacity: 1;
transform: translateX(0);
}
}
通过变量可灵活调整动画节奏和距离。
3️⃣ 蚂蚁线动画(Ants)
@keyframes ants-x {
0% { background-position: 0 0; }
100% { background-position: var(--tv-motion-ants-shift, 8px) 0; }
}
在组件中调用:
.copyed-borders {
--tv-motion-ants-shift: 13px;
.border-top {
animation: ants-x var(--tv-motion-ants-speed) linear infinite;
}
}
六、组件集成方式
| 方式 | 描述 |
|---|---|
| 全局引入 | 在motion/index.less 统一引入所有动效,确保全局可用 |
| 局部调用 | 组件通过类名或 animation 属性使用对应动效 |
| 变量覆盖 | 通过覆盖 CSS 变量实现不同组件动效差异化 |
七、实践经验与优化建议
✅ 保持命名规范:保证语义清晰、避免重复
✅ 文件分类明确:不同类型动效分文件管理
✅ 加注释和示例:便于团队协作与复用
关于OpenTiny
欢迎加入 OpenTiny 开源社区。添加微信小助手:opentiny-official 一起参与交流前端技术~
OpenTiny 官网:opentiny.design
OpenTiny 代码仓库:github.com/opentiny
TinyVue源码:github.com/opentiny/ti…
欢迎进入代码仓库 Star🌟TinyVue、TinyEngine、TinyPro、TinyNG、TinyCLI、TinyEditor 如果你也想要共建,可以进入代码仓库,找到 good first issue标签,一起参与开源贡献~