🎉 Vue2 过渡动画与 Animate.css 整合指南

This commit is contained in:
bunny 2025-06-21 23:53:33 +08:00
parent 76ef5f7e5b
commit 3872c8f29e
5 changed files with 194 additions and 6 deletions

View File

@ -9,6 +9,7 @@
"lint": "vue-cli-service lint" "lint": "vue-cli-service lint"
}, },
"dependencies": { "dependencies": {
"animate.css": "^4.1.1",
"core-js": "^3.8.3", "core-js": "^3.8.3",
"nanoid": "^5.1.5", "nanoid": "^5.1.5",
"vue": "^2.6.14", "vue": "^2.6.14",

View File

@ -8,6 +8,9 @@ importers:
.: .:
dependencies: dependencies:
animate.css:
specifier: ^4.1.1
version: 4.1.1
core-js: core-js:
specifier: ^3.8.3 specifier: ^3.8.3
version: 3.43.0 version: 3.43.0
@ -1034,6 +1037,9 @@ packages:
ajv@8.17.1: ajv@8.17.1:
resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==}
animate.css@4.1.1:
resolution: {integrity: sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ==}
ansi-colors@4.1.3: ansi-colors@4.1.3:
resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==}
engines: {node: '>=6'} engines: {node: '>=6'}
@ -5245,6 +5251,8 @@ snapshots:
json-schema-traverse: 1.0.0 json-schema-traverse: 1.0.0
require-from-string: 2.0.2 require-from-string: 2.0.2
animate.css@4.1.1: {}
ansi-colors@4.1.3: {} ansi-colors@4.1.3: {}
ansi-escapes@3.2.0: {} ansi-escapes@3.2.0: {}

View File

@ -1,3 +1,4 @@
import "animate.css";
import Vue from "vue"; import Vue from "vue";
import VueRouter from "vue-router"; import VueRouter from "vue-router";
import App from "./App.vue"; import App from "./App.vue";

View File

@ -0,0 +1,166 @@
# Vue2 过渡动画与 Animate.css 整合指南
## 一、Transition 与 TransitionGroup 对比
| 特性 | Transition | TransitionGroup |
| -------- | ----------------- | --------------- |
| 用途 | 单个元素/组件过渡 | 列表项过渡 |
| 要求 | 需要条件渲染 | 需要 `key` 属性 |
| 动画类 | 自动生成 | 可自定义类名 |
| 额外效果 | - | 自动处理定位 |
## 二、Animate.css 集成方案
### 1. 基本集成方法
```html
<TransitionGroup
name="animate__animated animate__bounce"
appear
enter-active-class="animate__flipInX"
leave-active-class="animate__flipOutX"
>
<!-- 列表项 -->
</TransitionGroup>
```
### 2. 常用动画效果
| 进入效果 | 离开效果 | 说明 |
| ---------------------- | ------------------------ | -------- |
| `animate__fadeIn` | `animate__fadeOut` | 淡入淡出 |
| `animate__zoomIn` | `animate__zoomOut` | 缩放效果 |
| `animate__slideInLeft` | `animate__slideOutRight` | 滑动效果 |
| `animate__flipInX` | `animate__flipOutX` | 3D翻转 |
## 三、自定义动画与库动画结合
### 1. 混合使用示例
```html
<!-- 自定义单个元素动画 -->
<Transition name="bunny">
<h3 v-show="visibility">自定义动画</h3>
</Transition>
<!-- Animate.css 列表动画 -->
<TransitionGroup
enter-active-class="animate__animated animate__fadeInUp"
leave-active-class="animate__animated animate__fadeOutDown"
>
<li v-for="item in items" :key="item.id">{{ item.text }}</li>
</TransitionGroup>
```
### 2. 动画性能优化
```css
/* 启用GPU加速 */
.animate__animated {
animation-duration: 0.5s;
backface-visibility: hidden;
}
/* 限制动画影响范围 */
.bunny-enter-active, .bunny-leave-active {
will-change: transform;
isolation: isolate;
}
```
## 四、最佳实践建议
### 1. 动画选择原则
- **移动端**使用较轻量的动画如fade
- **重要交互**使用明显的反馈动画如bounce
- **连续操作**:保持动画风格一致
### 2. 时间控制技巧
```javascript
// 动态控制动画时长
data() {
return {
duration: window.innerWidth < 768 ? 300 : 500
}
}
```
### 3. 无障碍访问
```css
/* 减少运动偏好设置 */
@media (prefers-reduced-motion: reduce) {
.animate__animated,
.bunny-enter-active,
.bunny-leave-active {
animation: none !important;
transition: none !important;
}
}
```
## 五、进阶应用场景
### 1. 路由过渡动画
```html
<Transition :name="transitionName" mode="out-in">
<router-view></router-view>
</Transition>
<script>
export default {
data() {
return {
transitionName: 'slide'
}
},
watch: {
'$route'(to, from) {
this.transitionName = to.meta.transition || 'fade'
}
}
}
</script>
```
### 2. 状态驱动的动画
```javascript
computed: {
animationClass() {
return this.isError
? 'animate__shakeX'
: 'animate__tada'
}
}
```
### 3. 动画事件钩子
```html
<Transition
@before-enter="beforeEnter"
@after-enter="afterEnter"
>
<div v-if="show">内容</div>
</Transition>
<script>
methods: {
beforeEnter(el) {
el.style.opacity = 0
},
afterEnter(el) {
// 动画结束后的处理
}
}
</script>
```
## 六、常见问题解决
1. **动画不连贯**
- 使用 `mode="out-in"` 确保顺序执行
- 检查 `key` 属性是否唯一
2. **初始渲染无动画**
- 添加 `appear` 属性
- 检查初始状态是否正确
3. **移动端性能差**
- 减少动画复杂度
- 使用 `will-change` 提示浏览器优化

View File

@ -1,14 +1,26 @@
<template> <template>
<div class="card"> <div class="container card">
<div class="card-header"> <div class="card-header">
<h1>动画效果:{{ visibility }}</h1> <h1>动画效果:{{ visibility }}</h1>
</div> </div>
<Transition name="bunny" :appear="true"> <div class="card-body">
<div class="card-body" v-show="visibility"> <Transition name="bunny" :appear="true">
<h3>显示动画</h3> <h3 v-show="visibility">显示动画</h3>
</div> </Transition>
</Transition>
<ul>
<TransitionGroup
name="animate__animated animate__bounce"
appear
enter-active-class="animate__flipInX"
leave-active-class="animate__flipOutX"
>
<li key="1" v-show="visibility">嗬嗬嗬嗬嗬嗬嗬嗬嗬嗬嗬</li>
<li key="2" v-show="!visibility">哈哈哈哈哈哈哈哈哈哈哈</li>
</TransitionGroup>
</ul>
</div>
<div class="card-footer"> <div class="card-footer">
<div class="btn-group"> <div class="btn-group">