【愚公系列】《循序渐进Vue.js 3.x前端开发实践》040-Vue过渡动画
标题 | 详情 |
---|---|
作者简介 | 愚公搬代码 |
头衔 | 华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。 |
近期荣誉 | 2022年度博客之星TOP2,2023年度博客之星TOP2,2022年华为云十佳博主,2023年华为云十佳博主,2024年华为云十佳博主等。 |
博客内容 | .NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。 |
欢迎 | 👍点赞、✍评论、⭐收藏 |
文章目录
- 🚀前言
- 🚀一、Vue过渡动画<transition>
- 🔎1. HTML 结构和 Vue 初始化
- 🦋1.1 关键点
- 🔎2. CSS 部分:过渡动画和关键帧
- 🦋2.1 关键帧动画:
- 🦋2.2 过渡状态类:
- 🔎3. Vue 逻辑部分
- 🦋3.1 响应式数据:
- 🦋3.2 点击事件:
- 🦋3.3 Vue 挂载:
- 🔎4. 过渡动画的工作原理
- 🔎5. 总结
- 🚀二、Vue过渡动画事件
- 🔎1. HTML 结构和 Vue 初始化
- 🦋1.1 关键点
- 🔎2. CSS 部分:过渡动画和关键帧
- 🦋2.1 关键帧动画:
- 🦋2.2 过渡状态类:
- 🔎3. Vue 逻辑部分
- 🦋3.1 响应式数据:
- 🦋3.2 `click` 方法:
- 🦋3.3 过渡生命周期钩子:
- 🦋3.4 Vue 挂载:
- 🔎4. 过渡动画的工作原理
- 🔎5. 过渡动画的执行流程
- 🔎6. 总结过渡动画的实现
- 🔎7. 改进与扩展建议
- 🚀三、多个组件的过渡动画
- 🔎1. HTML 结构
- 🦋1.1 HTML 结构分析
- 🔎2. CSS 样式与动画
- 🦋2.1 过渡动画类
- 🦋2.2 过渡效果的实现
- 🔎3. Vue 逻辑与组件
- 🦋3.1 Vue 组件分析
- 🦋3.2 Vue 响应式数据
- 🔎4. 过渡的工作流程
- 🔎5. 动画流程总结
- 🔎6. Vue 与 CSS 过渡结合的关键点
- 🔎7. 优化与扩展建议
- 🔎8. 总结
- 🚀四、列表过渡动画
- 🔎1. HTML 结构
- 🔎2. 代码解析
- 🦋2.1 HTML 结构
- 🦋2.2 Vue 组件与响应式数据
- 🦋2.3 过渡动画样式
- 🦋2.4 `transition-group` 的作用
- 🦋2.5 Vue 的响应式更新与过渡动画
- 🔎3. 交互与效果
- 🔎4. 详细的过渡动画流程
- 🦋4.1 进入动画(添加元素)
- 🦋4.2 离开动画(删除元素)
- 🦋4.3 元素移动动画(重排元素)
- 🦋4.4 关于 `transition-group` 的优势
- 🔎5. Vue 3 响应式系统与过渡动画结合
- 🔎6. 改进和优化建议
- 🦋6.1 性能优化
- 🦋6.2 CSS 动画效果的增强
- 🦋6.3 增强可访问性
- 🦋6.4 定制化动画时长
- 🦋6.5 兼容性考虑
- 🔎7. 总结
🚀前言
在现代 web 开发中,用户体验的好坏往往直接影响到用户的满意度和网站的使用率。动画效果作为提升用户体验的重要手段,可以让界面更加生动和互动。Vue.js 作为一个渐进式框架,不仅提供了强大的数据绑定功能,还使得实现过渡动画变得简单而直观。
本篇文章将深入探讨 Vue.js 中的过渡动画。我们将介绍 Vue 自带的 组件,如何利用它来为元素的进入、离开和状态变化添加流畅的过渡效果。通过具体的实例,我们将展示如何使用 CSS 过渡、动画以及 JavaScript 钩子函数,来创建多种样式的动画效果。
🚀一、Vue过渡动画
🔎1. HTML 结构和 Vue 初始化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<title>Vue过渡动画</title>
</head>
<body>
<style>
/* CSS 动画 */
</style>
<div id="Application">
<button @click="click">显示/隐藏</button>
<transition name="ani">
<div v-if="show" class="demo"></div>
</transition>
</div>
<script>
/* Vue 代码 */
</script>
</body>
</html>
🦋1.1 关键点
- Vue 3 引入:通过
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
引入 Vue 3 的全局版本。 <button>
元素:用户点击这个按钮时,会触发click
方法来控制div
元素的显示和隐藏。<transition>
组件:Vue 提供的过渡组件,用来包裹需要做过渡动画的元素。此处包裹的是div
元素,指定了一个过渡名称ani
,该名称会用于匹配相应的 CSS 类。
🔎2. CSS 部分:过渡动画和关键帧
@keyframes keyframe-in {
from {
width: 0px;
height: 0px;
background-color: red;
}
to {
width: 100px;
height: 100px;
background-color: blue;
}
}
@keyframes keyframe-out {
from {
width: 100px;
height: 100px;
background-color: blue;
}
to {
width: 0px;
height: 0px;
background-color: red;
}
}
.demo {
width: 100px;
height: 100px;
background-color: blue;
}
.ani-enter-from {
width: 0px;
height: 0px;
background-color: red;
}
.ani-enter-active {
animation: keyframe-in 3s;
}
.ani-enter-to {
width: 100px;
height: 100px;
background-color: blue;
}
.ani-leave-from {
width: 100px;
height: 100px;
background-color: blue;
}
.ani-leave-active {
animation: keyframe-out 3s;
}
.ani-leave-to {
width: 0px;
height: 0px;
background-color: red;
}
🦋2.1 关键帧动画:
keyframe-in
:当元素显示时,动画从width: 0px
和height: 0px
开始,背景色是红色,最后过渡到width: 100px
和height: 100px
,背景色变为蓝色。keyframe-out
:当元素隐藏时,动画从width: 100px
和height: 100px
开始,背景色是蓝色,最后过渡到width: 0px
和height: 0px
,背景色变为红色。
🦋2.2 过渡状态类:
.ani-enter-from
:元素进入前的初始状态,宽度和高度为0px
,背景色为红色。.ani-enter-active
:进入过程中的活动状态,使用keyframe-in
动画,持续 3 秒。.ani-enter-to
:元素进入后的最终状态,宽度和高度为100px
,背景色为蓝色。.ani-leave-from
:元素离开前的初始状态,宽度和高度为100px
,背景色为蓝色。.ani-leave-active
:离开过程中的活动状态,使用keyframe-out
动画,持续 3 秒。.ani-leave-to
:元素离开后的最终状态,宽度和高度为0px
,背景色为红色。
这些 CSS 类通过 Vue 的 <transition>
组件的生命周期钩子来自动添加和移除,从而触发过渡动画。
🔎3. Vue 逻辑部分
const { createApp, ref } = Vue;
const App = createApp({
setup() {
const show = ref(false); // 控制 div 显示和隐藏的响应式数据
const click = () => {
show.value = !show.value; // 切换 show 的值,实现显示/隐藏
};
return { show, click };
}
});
App.mount("#Application");
🦋3.1 响应式数据:
const show = ref(false);
:show
是一个响应式数据,初始值为false
,表示div
元素不显示。
🦋3.2 点击事件:
const click = () => { show.value = !show.value; };
:click
方法通过切换show
的值来控制div
元素的显示或隐藏。每次点击按钮时,show
的值会在true
和false
之间切换,从而触发v-if
的条件渲染。
🦋3.3 Vue 挂载:
App.mount("#Application");
:这行代码将 Vue 应用挂载到页面上id="Application"
的div
元素中。
🔎4. 过渡动画的工作原理
<transition>
:Vue 会在元素的进入和离开过程中自动为其添加相应的过渡类。这些类的命名规则是:name-*-from
、name-*-active
和name-*-to
,其中name
是<transition>
标签上的name
属性的值(这里是ani
)。- 当
show
的值为true
时,v-if="show"
会使div
元素渲染,并应用ani-enter-*
类,从而触发元素的进入动画。 - 当
show
的值为false
时,div
元素会被销毁,触发ani-leave-*
类,从而触发元素的离开动画。
🔎5. 总结
- 功能:点击按钮时,
div
元素会通过过渡动画在显示和隐藏之间切换,动画包括宽度、高度和背景色的变化。 - Vue 过渡机制:通过
<transition>
组件和生命周期类(enter
和leave
),Vue 能够在元素进入和离开时自动添加和移除适当的 CSS 类,从而触发动画。 - CSS 动画:使用
@keyframes
创建了两个关键帧动画,分别控制元素进入和离开时的尺寸变化和背景颜色变化。
整体来说,这段代码演示了如何结合 Vue 过渡机制与 CSS 动画,实现一个平滑的显示/隐藏动画效果。
🚀二、Vue过渡动画事件
🔎1. HTML 结构和 Vue 初始化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<title>Vue过渡动画</title>
</head>
<body>
<style>
/* CSS 动画定义 */
</style>
<div id="Application">
<button @click="click">显示/隐藏</button>
<transition
name="ani"
appear
@before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter"
@enter-cancelled="enterCancelled"
@before-leave="beforeLeave"
@leave="leave"
@after-leave="afterLeave"
@leave-cancelled="leaveCancelled">
<div v-show="show" class="demo"></div>
</transition>
</div>
<script>
/* Vue 代码 */
</script>
</body>
</html>
🦋1.1 关键点
<button @click="click">
:用户点击按钮时,会触发click
方法,控制div
元素的显示或隐藏。<transition>
组件:Vue 的<transition>
组件用来包裹带有过渡效果的元素,并且通过name
属性指定过渡效果的类名前缀。这里使用了多个 Vue 的生命周期钩子,来处理元素的进入和离开。v-show="show"
:v-show
是 Vue 提供的指令,用于控制元素的显示与隐藏。show
是响应式的,当其值为true
时,div
元素会显示,值为false
时,元素隐藏。
🔎2. CSS 部分:过渡动画和关键帧
@keyframes keyframe-in {
from {
width: 0px;
height: 0px;
background-color: red;
}
to {
width: 100px;
height: 100px;
background-color: blue;
}
}
@keyframes keyframe-out {
from {
width: 100px;
height: 100px;
background-color: blue;
}
to {
width: 0px;
height: 0px;
background-color: red;
}
}
.demo {
width: 100px;
height: 100px;
background-color: blue;
}
.ani-enter-from {
width: 0px;
height: 0px;
background-color: red;
}
.ani-enter-active {
animation: keyframe-in 3s;
}
.ani-enter-to {
width: 100px;
height: 100px;
background-color: blue;
}
.ani-leave-from {
width: 100px;
height: 100px;
background-color: blue;
}
.ani-leave-active {
animation: keyframe-out 3s;
}
.ani-leave-to {
width: 0px;
height: 0px;
background-color: red;
}
🦋2.1 关键帧动画:
keyframe-in
:定义了元素进入时的动画,元素从width: 0px
和height: 0px
开始,背景色为红色,动画结束时,元素的宽度和高度变为100px
,背景色变为蓝色。keyframe-out
:定义了元素离开时的动画,元素从width: 100px
和height: 100px
开始,背景色为蓝色,动画结束时,元素的宽度和高度变为0px
,背景色变为红色。
🦋2.2 过渡状态类:
.ani-enter-from
:元素进入前的初始状态,宽度和高度为0px
,背景色为红色。.ani-enter-active
:进入过程中使用的类,执行keyframe-in
动画,持续时间为 3 秒。.ani-enter-to
:元素进入后的最终状态,宽度和高度为100px
,背景色为蓝色。.ani-leave-from
:元素离开前的初始状态,宽度和高度为100px
,背景色为蓝色。.ani-leave-active
:离开过程中使用的类,执行keyframe-out
动画,持续时间为 3 秒。.ani-leave-to
:元素离开后的最终状态,宽度和高度为0px
,背景色为红色。
🔎3. Vue 逻辑部分
const { createApp, ref } = Vue;
const App = createApp({
setup() {
const show = ref(false); // 控制 div 显示和隐藏的响应式数据
const click = () => {
show.value = !show.value; // 切换 show 的值,实现显示/隐藏
};
// 过渡生命周期钩子函数
const beforeEnter = (el) => {
console.log("beforeEnter"); // 进入前调用
};
const enter = (el, done) => {
console.log("enter"); // 进入过程中调用
done(); // 调用 done() 以告知 Vue 动画完成
};
const afterEnter = (el) => {
console.log("afterEnter"); // 进入后调用
};
const enterCancelled = (el) => {
console.log("enterCancelled"); // 进入被取消时调用
};
const beforeLeave = (el) => {
console.log("beforeLeave"); // 离开前调用
};
const leave = (el, done) => {
console.log("leave"); // 离开过程中调用
done(); // 调用 done() 以告知 Vue 动画完成
};
const afterLeave = (el) => {
console.log("afterLeave"); // 离开后调用
};
const leaveCancelled = (el) => {
console.log("leaveCancelled"); // 离开被取消时调用
};
return { show, click, beforeEnter, enter, afterEnter, enterCancelled, beforeLeave, leave, afterLeave, leaveCancelled };
}
});
App.mount("#Application");
🦋3.1 响应式数据:
const show = ref(false);
:show
是响应式数据,用于控制div
元素是否显示。初始值为false
,即div
元素默认隐藏。
🦋3.2 click
方法:
click
方法每次点击按钮时,切换show
的值,控制div
元素的显示或隐藏。
🦋3.3 过渡生命周期钩子:
@before-enter
:元素进入前触发,调用beforeEnter
方法并输出 “beforeEnter”。@enter
:元素进入时触发,调用enter
方法并输出 “enter”。该方法中的done()
是必须的,它告知 Vue 动画完成,可以开始下一个阶段。@after-enter
:元素进入后触发,调用afterEnter
方法并输出 “afterEnter”。@enter-cancelled
:元素进入动画被取消时触发,调用enterCancelled
方法并输出 “enterCancelled”。@before-leave
:元素离开前触发,调用beforeLeave
方法并输出 “beforeLeave”。@leave
:元素离开时触发,调用leave
方法并输出 “leave”。同样,done()
必须调用,告知 Vue 动画完成。@after-leave
:元素离开后触发,调用afterLeave
方法并输出 “afterLeave”。@leave-cancelled
:元素离开动画被取消时触发,调用leaveCancelled
方法并输出 “leaveCancelled”。
🦋3.4 Vue 挂载:
App.mount("#Application");
:将 Vue 应用挂载到id="Application"
的元素上。
🔎4. 过渡动画的工作原理
<transition>
组件的生命周期钩子:这些钩子允许你在过渡的不同阶段执行自定义操作,比如日志输出或其他操作。每个生命周期钩子都对应于一个过渡的阶段(如元素进入前、进入过程中、离开后等)。done()
函数:在enter
和leave
生命周期钩子中,done()
函数的调用是非常重要的。当 Vue 执行进入或离开动画时,done()
需要被调用,以告知 Vue 动画已经完成或者被取消。如果不调用done()
,Vue 会一直等待,直到超时或者动画被强制中止。
🔎5. 过渡动画的执行流程
-
点击按钮时触发
click
方法:click
方法切换show
的值,如果当前是false
,则将其设置为true
,使得div
元素显示;如果当前是true
,则将其设置为false
,使得div
元素隐藏。
-
元素显示时的过渡流程:
- 当
div
元素显示(v-show="show"
)时,Vue 会触发元素的 进入过渡。 @before-enter
:在元素开始进入前执行beforeEnter
方法,输出"beforeEnter"
。@enter
:元素进入过程中会触发enter
钩子。此时可以执行动画的实际操作。动画开始时调用done()
来告知 Vue 动画完成。@after-enter
:动画结束后执行afterEnter
方法,输出"afterEnter"
。
- 当
-
元素隐藏时的过渡流程:
- 当
div
元素隐藏(v-show="show"
)时,Vue 会触发元素的 离开过渡。 @before-leave
:在元素开始离开前执行beforeLeave
方法,输出"beforeLeave"
。@leave
:元素离开过程中会触发leave
钩子。此时可以执行离开的动画操作。动画结束时,调用done()
来告知 Vue 动画完成。@after-leave
:动画结束后执行afterLeave
方法,输出"afterLeave"
。
- 当
-
取消过渡动画:
- 如果动画被取消(例如,在过渡过程中切换了
show
值),则会触发对应的取消钩子。 @enter-cancelled
:如果进入动画被取消,则执行enterCancelled
方法,输出"enterCancelled"
。@leave-cancelled
:如果离开动画被取消,则执行leaveCancelled
方法,输出"leaveCancelled"
。
- 如果动画被取消(例如,在过渡过程中切换了
🔎6. 总结过渡动画的实现
- 过渡动画:通过 CSS 中的
@keyframes
定义进入和离开的动画,使用@enter-active
和@leave-active
绑定这些动画。Vue 会根据元素的状态(显示或隐藏)自动应用这些动画。 - 生命周期钩子:Vue 提供的
@before-enter
、@enter
、@after-enter
、@enter-cancelled
等钩子让你可以在不同阶段执行自定义操作。这些钩子对于调试或执行其他任务(如网络请求、数据处理等)非常有用。 done()
函数:在@enter
和@leave
钩子中,done()
函数的调用是必须的,用来告诉 Vue 动画何时完成。
🔎7. 改进与扩展建议
- 使用 CSS 类控制样式:目前使用了 Vue 动画钩子和 CSS 关键帧动画。如果动画效果复杂,可以将一些动画分离到外部 CSS 文件中,减少 Vue 组件的复杂度。
- 添加更多过渡效果:可以扩展过渡效果,比如缩放、旋转等,以使 UI 动效更加生动。
- 优化性能:对于频繁显示或隐藏的元素,Vue 的
v-show
比v-if
更高效,因为v-show
只是切换元素的display
属性,而不会移除 DOM。对于复杂的动画,避免在过渡期间做过多的 DOM 操作。
这段代码是一个很好的示例,展示了如何在 Vue 中使用过渡动画以及如何结合生命周期钩子来执行动画中的不同阶段的操作。
🚀三、多个组件的过渡动画
🔎1. HTML 结构
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<title>Vue过渡动画</title>
</head>
<body>
<style> ... </style>
<div id="Application">
<button @click="click">显示/隐藏</button>
<transition name="ani" mode="in-out">
<div v-if="show" class="demo"></div>
<div v-else class="demo2"></div>
</transition>
</div>
<script> ... </script>
</body>
</html>
🦋1.1 HTML 结构分析
-
<button @click="click">
:这是一个按钮,点击时会调用 Vue 组件中的click
方法,切换show
的值,从而触发div
元素的显示或隐藏。 -
<transition name="ani" mode="in-out">
:这是 Vue 提供的<transition>
组件,包裹了要进行过渡动画的元素。name="ani"
指定了过渡的类名前缀。mode="in-out"
表示当元素进入时,离开的元素会等待新元素完全进入后才开始离开(即进入和离开过渡动画是互斥的)。 -
<div v-if="show" class="demo">
:这是一个带有v-if="show"
的div
,如果show
的值为true
,该div
会显示。它有一个类名demo
,用于定义进入时的动画样式。 -
<div v-else class="demo2">
:这是一个带有v-else
的div
,如果show
的值为false
,该div
会显示。它有一个类名demo2
,用于定义离开时的动画样式。
🔎2. CSS 样式与动画
.demo {
width: 100px;
height: 100px;
background-color: blue;
}
.demo2 {
width: 100px;
height: 100px;
background-color: blue;
}
.ani-enter-from {
width: 0px;
height: 0px;
background-color: red;
}
.ani-enter-active {
transition: width 3s, height 3s, background-color 3s;
}
.ani-enter-to {
width: 100px;
height: 100px;
background-color: blue;
}
.ani-leave-from {
width: 100px;
height: 100px;
background-color: blue;
}
.ani-leave-active {
transition: width 3s, height 3s, background-color 3s;
}
.ani-leave-to {
width: 0px;
height: 0px;
background-color: red;
}
🦋2.1 过渡动画类
-
.demo
和.demo2
:这两个类是div
元素的基本样式。它们设置了元素的宽度、高度和背景颜色。demo
和demo2
的差异仅在于用来区别显示的两个元素,动画效果并不直接作用于它们。 -
进入过渡的类:
.ani-enter-from
:当元素开始进入时,它的初始状态。元素的宽度和高度为0px
,背景色为红色。.ani-enter-active
:定义了进入过程的动画效果,指定了元素的宽度、背景色和高度在 3 秒内的过渡效果。即元素的宽度、背景色和高度会在 3 秒内从初始状态逐渐变化。.ani-enter-to
:当元素完全进入时,它的最终状态。宽度和高度变为100px
,背景色变为蓝色。
-
离开过渡的类:
.ani-leave-from
:当元素开始离开时,它的初始状态。此时元素的宽度和高度为100px
,背景色为蓝色。.ani-leave-active
:定义了离开过程的动画效果,宽度、背景色和高度在 3 秒内的过渡效果。.ani-leave-to
:当元素完全离开时,它的最终状态。宽度和高度变为0px
,背景色变为红色。
🦋2.2 过渡效果的实现
-
.ani-enter-active
和.ani-leave-active
:这两个类用于分别定义进入和离开动画的时长和效果(在这里是width
、height
和background-color
属性的 3 秒过渡)。它们确保在进入或离开的过程中,元素的尺寸和背景色平滑过渡。 -
transition: width 3s, height 3s, background-color 3s;
:这行 CSS 表示元素在 3 秒内会平滑地过渡这三个属性(宽度、高度和背景色)。transition
是 CSS 提供的过渡效果,使元素在状态改变时显示出平滑的变化。
🔎3. Vue 逻辑与组件
const App = Vue.createApp({
setup() {
const show = Vue.ref(false) // `show` 是一个响应式数据,控制 div 的显示或隐藏
const click = () => {
show.value = !show.value // 点击按钮时切换 `show` 的值
}
return { show, click }
}
})
App.mount("#Application")
🦋3.1 Vue 组件分析
-
Vue.createApp()
:通过Vue.createApp()
创建一个 Vue 应用实例。setup()
是 Vue 3 中的 Composition API 函数,它用于声明响应式数据和方法。 -
show
:show
是一个响应式变量,初始化为false
,控制元素的显示或隐藏。v-if="show"
会根据show
的值决定是否渲染第一个div
(类名为.demo
),如果show
为false
,则渲染v-else
中的第二个div
(类名为.demo2
)。 -
click
:click
是一个函数,它的作用是切换show
的布尔值。每次点击按钮时,show
值会从true
切换到false
或反之,从而触发 Vue 的条件渲染和过渡动画。
🦋3.2 Vue 响应式数据
-
const show = Vue.ref(false)
:通过Vue.ref()
创建了一个响应式的数据show
,并初始化为false
。这意味着 Vue 会自动追踪show
的变化,并在值变化时更新视图。 -
@click="click"
:按钮的点击事件绑定到了click
方法。点击按钮时会触发click
方法,切换show
的值,从而控制两个div
的显示与隐藏。
🔎4. 过渡的工作流程
-
初始状态:页面加载时,
show
初始化为false
,因此显示的是第二个div
(类名为.demo2
),背景色为蓝色,大小为 100x100px。 -
点击按钮切换状态:点击按钮时,
show
值变为true
,Vue 会首先从 DOM 中移除第二个div
(类名.demo2
),并开始渲染第一个div
(类名.demo
)。 -
元素进入的过渡:
ani-enter-from
:新渲染的元素从width: 0px
,height: 0px
和background-color: red
开始。ani-enter-active
:元素的宽度、高度和背景色会在 3 秒内过渡到最终状态。ani-enter-to
:过渡结束时,元素的尺寸变为 100px,背景色变为蓝色。
-
点击按钮再次切换状态:再次点击按钮,
show
值变为false
,Vue 会开始渲染第二个div
并移除第一个div
。 -
元素离开的过渡:
ani-leave-from
:离开的元素从width: 100px
,height: 100px
和background-color: blue
开始,表示当前显示的元素的初始状态。
-
ani-leave-active
:离开动画的过渡效果,元素的宽度、高度和背景色将在 3 秒内过渡到目标状态。 -
ani-leave-to
:过渡结束时,元素的尺寸将变为0px
,背景色变为红色。
🔎5. 动画流程总结
-
当点击按钮时,Vue 会自动触发
v-if
和v-else
的切换,显示或隐藏对应的div
。 -
在显示或隐藏元素的过程中,Vue 使用了
<transition>
包裹元素,并且通过设置name="ani"
和定义相关的 CSS 类名,使得在进入和离开元素时应用过渡动画。动画的过程由以下几个阶段组成:-
进入阶段(Enter):
- 从
ani-enter-from
开始(初始状态:尺寸为 0px,背景色为红色)。 - 然后进入
ani-enter-active
状态,过渡动画开始,尺寸和背景色变化。 - 最后过渡到
ani-enter-to
,元素达到最终状态(宽度和高度为 100px,背景色为蓝色)。
- 从
-
离开阶段(Leave):
- 离开时,首先从
ani-leave-from
开始(当前状态:尺寸为 100px,背景色为蓝色)。 - 然后进入
ani-leave-active
状态,过渡动画开始,尺寸和背景色变化。 - 最后过渡到
ani-leave-to
,元素的尺寸变为 0px,背景色变为红色。
- 离开时,首先从
-
🔎6. Vue 与 CSS 过渡结合的关键点
-
v-if
和v-else
:Vue 用于条件渲染。当show
为true
时,显示.demo
,为false
时,显示.demo2
。通过切换这两个div
,配合 Vue 提供的<transition>
组件,可以在元素进出时应用过渡效果。 -
<transition>
组件:Vue 的<transition>
组件自动处理了进入和离开动画。通过设置name="ani"
,Vue 会根据元素的进入和离开状态自动为元素添加不同的类名(如.ani-enter-from
、.ani-enter-active
等)。这使得开发者可以用 CSS 来定义过渡动画。 -
transition
属性:CSS 的transition
属性用于定义元素在过渡过程中各个属性(如width
、height
和background-color
)的变化过程和时长。通过transition
,可以使得元素的尺寸和颜色等在指定的时间内平滑变化。 -
mode="in-out"
:Vue 的mode="in-out"
确保了元素进入时,离开的元素会等待新元素完全进入后才开始离开。这对于同时进行进入和离开动画时特别有用,避免了动画的冲突或重叠。
🔎7. 优化与扩展建议
-
动画时长与优化:
- 在当前的实现中,动画时长是硬编码为 3 秒。如果你希望动态控制动画时长,可以通过 Vue 的数据绑定或动态样式来实现,或者使用
v-bind:style
动态调整transition
的持续时间。
- 在当前的实现中,动画时长是硬编码为 3 秒。如果你希望动态控制动画时长,可以通过 Vue 的数据绑定或动态样式来实现,或者使用
-
过渡效果种类:
- 目前动画只涉及了
width
、height
和background-color
的变化。如果你想要更复杂的动画效果,可以使用transform
(如缩放、旋转、平移等)来增强视觉效果。例如,使用scale()
或translate()
等 CSS 函数来控制元素的变换。
- 目前动画只涉及了
-
避免硬编码颜色:
- 可以将颜色从硬编码的
red
和blue
改为 CSS 变量或从外部配置文件传入,这样更具灵活性,尤其是在项目中使用主题或样式切换时。
- 可以将颜色从硬编码的
-
改进过渡时的性能:
- 如果页面中有多个元素需要进行过渡,过渡动画可能会影响页面性能。为了提升性能,可以只对少量最关键的元素应用过渡动画,或者通过减少动画的时长和复杂度来提高响应速度。
🔎8. 总结
这段代码展示了如何在 Vue 3 中结合条件渲染(v-if
和 v-else
)与 CSS 动画来实现简单的过渡动画。通过 Vue 的 <transition>
组件,开发者可以轻松地为元素的显示和隐藏应用动画效果。动画的实现通过 CSS 过渡来完成,利用 transition
属性控制元素尺寸、背景色等的平滑变化。
- Vue:通过响应式数据
show
控制元素的显示和隐藏,click
方法切换show
的值。 - CSS 过渡:利用
transition
和动画的from
、active
、to
状态来实现元素的进入和离开动画效果。
这种方法简单且易于理解,适用于页面中需要实现元素显隐过渡效果的场景。
🚀四、列表过渡动画
🔎1. HTML 结构
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<title>Vue过渡动画</title>
</head>
<body>
<style>
.list-enter-active,
.list-leave-active {
transition: all 1s ease;
}
.list-enter-from,
.list-leave-to {
opacity: 0;
}
.list-move {
transition: transform 1s ease;
}
</style>
<div id="Application">
<button @click="click">添加元素</button>
<button @click="dele">删除元素</button>
<button @click="sort">重排元素</button>
<transition-group name="list">
<div v-for="item in items" :key="item">
元素:{{ item }}
</div>
</transition-group>
</div>
<script>
const { createApp, ref } = Vue;
const App = Vue.createApp({
setup() {
const items = ref([1, 2, 3, 4, 5]);
const click = () => {
items.value.push(items.value[items.value.length - 1] + 1);
};
const dele = () => {
if (items.value.length > 0) {
items.value.pop();
}
};
const sort = () => {
items.value.reverse();
};
return { items, dele, sort, click };
}
});
App.mount("#Application");
</script>
</body>
</html>
🔎2. 代码解析
🦋2.1 HTML 结构
-
<button @click="click">添加元素</button>
:这是一个按钮,点击时会调用 Vue 组件中的click
方法,添加一个新的元素到items
列表中。 -
<button @click="dele">删除元素</button>
:这是一个按钮,点击时会调用dele
方法,删除items
列表中的最后一个元素。 -
<button @click="sort">重排元素</button>
:这是一个按钮,点击时会调用sort
方法,反转items
列表的顺序。 -
<transition-group name="list">
:Vue 的transition-group
组件用于处理多个元素的过渡效果。它会包裹需要进行过渡的多个子元素。在这里,它包裹了通过v-for
渲染的每个div
元素,确保当列表中的元素发生变化时,能平滑地进行动画过渡。
🦋2.2 Vue 组件与响应式数据
const { createApp, ref } = Vue;
const App = Vue.createApp({
setup() {
const items = ref([1, 2, 3, 4, 5]);
const click = () => {
items.value.push(items.value[items.value.length - 1] + 1);
};
const dele = () => {
if (items.value.length > 0) {
items.value.pop();
}
};
const sort = () => {
items.value.reverse();
};
return { items, dele, sort, click };
}
});
App.mount("#Application");
-
createApp
和ref
:createApp
是 Vue 3 的应用创建方法,ref
是用于创建响应式变量的方法。在这里,items
是一个响应式的数组,保存列表中的数字。 -
items
:这是一个响应式的数组,初始值为[1, 2, 3, 4, 5]
。每当这个数组发生变化时,Vue 会自动更新视图。 -
click
:点击按钮时会调用click
方法,它会向items
数组中添加一个新元素,这个元素是items
数组中最后一个元素的值加 1。 -
dele
:点击删除按钮时会调用dele
方法,它会删除items
数组中的最后一个元素(如果数组不为空)。 -
sort
:点击排序按钮时会调用sort
方法,它会反转items
数组中的元素顺序。
🦋2.3 过渡动画样式
.list-enter-active,
.list-leave-active {
transition: all 1s ease;
}
.list-enter-from,
.list-leave-to {
opacity: 0;
}
.list-move {
transition: transform 1s ease;
}
-
.list-enter-active
和.list-leave-active
:这两个类定义了进入和离开动画的过渡效果。transition: all 1s ease;
表示所有属性(如尺寸、颜色、位置等)在 1 秒内平滑过渡,使用ease
缓动函数。 -
.list-enter-from
和.list-leave-to
:这两个类分别定义了进入和离开时的初始/最终状态。在元素进入时,它的透明度设置为0
(完全透明),在离开时,它的透明度也为0
,即完全透明。 -
.list-move
:这个类定义了元素位置发生变化时的过渡效果。transition: transform 1s ease;
表示如果元素的位置发生变化(如排序),它会平滑地过渡 1 秒钟。
🦋2.4 transition-group
的作用
<transition-group>
是 Vue 提供的一个特殊的过渡组件,用于处理动态元素列表的过渡动画。它通过 name="list"
属性与上述 CSS 过渡类关联,确保当列表中的元素发生变化时(如添加、删除或排序),元素会平滑地过渡。
-
v-for="item in items"
:通过v-for
指令渲染items
数组中的每个元素,每个元素被渲染为一个div
元素。 -
:key="item"
:为每个div
元素指定一个唯一的key
,这对于 Vue 内部的差异化渲染和高效更新 DOM 至关重要。在这里,item
本身作为唯一标识。
🦋2.5 Vue 的响应式更新与过渡动画
- 当
items
数组的内容发生变化时(例如,通过click
、dele
或sort
方法),Vue 会自动更新视图并应用过渡效果。 - 添加元素:当新元素添加到
items
中时,<transition-group>
会处理新元素的进入动画(通过.list-enter-from
、.list-enter-active
和.list-enter-to
)。 - 删除元素:当元素从
items
中删除时,<transition-group>
会处理元素的离开动画(通过.list-leave-from
、.list-leave-active
和.list-leave-to
)。 - 重排元素:当
items
数组被反转时,<transition-group>
会应用.list-move
类,使元素位置发生平滑过渡。
🔎3. 交互与效果
-
添加元素:点击“添加元素”按钮时,
click
方法会向items
数组中添加一个新元素。该元素会通过过渡效果平滑地显示在列表中,opacity
从0
到1
,并且元素的位置可能会有小幅度的移动。 -
删除元素:点击“删除元素”按钮时,
dele
方法会删除items
数组中的最后一个元素。删除的元素会通过过渡动画消失,opacity
从1
到0
。 -
重排元素:点击“重排元素”按钮时,
sort
方法会反转items
数组的顺序。Vue 会平滑地移动这些元素的位置,应用.list-move
动画。
🔎4. 详细的过渡动画流程
在代码中,过渡动画的细节通过 transition-group
组件和相关的 CSS 类来管理。当列表中的元素添加、删除或重新排序时,Vue 会自动应用这些动画。具体流程如下:
🦋4.1 进入动画(添加元素)
- 操作:点击“添加元素”按钮时,会调用
click
方法向items
数组中添加一个新元素。 - CSS 动画:
- Vue 会为新添加的元素应用
.list-enter-from
类,并将该元素的opacity
设置为0
(完全透明)。 - 然后,元素会过渡到
.list-enter-active
类,逐渐变得完全可见,即opacity
从0
渐变到1
。 - 过渡持续时间是 1 秒钟(通过
transition: all 1s ease
实现),动画效果是线性的ease
缓动。 - 最终,元素进入并呈现完整的显示状态。
- Vue 会为新添加的元素应用
🦋4.2 离开动画(删除元素)
- 操作:点击“删除元素”按钮时,会调用
dele
方法删除items
数组中的最后一个元素。 - CSS 动画:
- Vue 会为即将删除的元素应用
.list-leave-to
类,并将其opacity
设置为0
(完全透明),使得元素看起来像是逐渐消失。 - 在删除前,元素会被赋予
.list-leave-active
类,这会导致它的透明度平滑地从1
渐变到0
。 - 过渡持续时间同样是 1 秒钟,采用
ease
缓动函数。 - 最终,元素会完全消失并从 DOM 中移除。
- Vue 会为即将删除的元素应用
🦋4.3 元素移动动画(重排元素)
- 操作:点击“重排元素”按钮时,会调用
sort
方法对items
数组进行反转。 - CSS 动画:
- Vue 会为排序过程中移动的元素应用
.list-move
类。 - 使用
transition: transform 1s ease
来平滑地过渡元素的变换,具体是平移或重新排列元素的位置。 - 通过
transform
属性,元素会在 1 秒内移动到新的位置,达到平滑过渡的效果。
- Vue 会为排序过程中移动的元素应用
🦋4.4 关于 transition-group
的优势
- 批量过渡:
transition-group
不仅适用于单个元素的过渡,它可以有效地为多个子元素(如列表项)应用动画。通过v-for
渲染多个元素时,transition-group
确保每个元素在增、删或排序时都能遵循相应的过渡规则。 - 元素的顺序变动:当元素顺序发生变化时(如使用
sort
方法反转数组),transition-group
会自动为这些元素的重新排列添加动画,使得移动过程更加平滑,而不仅仅是静态的重新渲染。
🔎5. Vue 3 响应式系统与过渡动画结合
- 响应式数据:Vue 3 使用响应式系统来管理应用的状态。
items
数组是响应式的,每当其内容发生变化时(如添加、删除或排序元素),Vue 会自动检测到变化并触发视图更新。 - 自动过渡处理:在此基础上,
<transition-group>
组件会自动为发生变化的元素应用过渡动画,而无需手动管理每个元素的入场、离场或移动动画。这是 Vue 3 中的一个强大特性,能够简化动画的管理。
🔎6. 改进和优化建议
虽然这个例子展示了 Vue 3 的过渡动画效果,但在实际生产环境中,可能会遇到一些性能和可维护性的问题。以下是一些可以改进或优化的建议:
🦋6.1 性能优化
- 大量元素的过渡:当列表中的元素非常多时,过渡动画可能会影响性能,特别是在低性能设备上。为了优化性能,可以考虑以下方法:
- 限制过渡动画的应用范围,只对需要动画的元素进行动画处理,而不是所有元素。
- 通过减少过渡时间或简化过渡效果(例如,使用
opacity
代替transform
或width
动画)来提高响应速度。 - 使用
will-change
CSS 属性,告诉浏览器该元素将会改变某些属性,这样浏览器可以优化渲染过程。
🦋6.2 CSS 动画效果的增强
- 更多动画效果:当前的动画只涉及透明度和位置变化。如果想让动画效果更加丰富,可以引入其他动画效果。例如:
- 使用
scale()
来创建缩放动画。 - 使用
rotate()
来实现旋转效果。 - 使用
translate3d()
来利用硬件加速优化动画的流畅度。
- 使用
🦋6.3 增强可访问性
- ARIA 标签:对于动态内容的变化,考虑添加一些 ARIA(无障碍富互联网应用)标签,以帮助屏幕阅读器用户识别哪些内容是新增、删除或重新排序的。例如,在元素的添加或删除时,可以动态地更新
aria-live
或aria-relevant
属性,以通知用户内容变化。
🦋6.4 定制化动画时长
- 动画控制:目前,所有过渡动画的时长都是固定为 1 秒。如果想要根据不同的操作(如添加、删除或排序)提供不同的动画效果,可以动态设置过渡时间。例如,可以在 Vue 中根据操作的类型动态设置动画时长:
const click = () => { items.value.push(items.value[items.value.length - 1] + 1); transitionDuration.value = '1s'; // 动态设置动画时长 };
🦋6.5 兼容性考虑
- 浏览器兼容性:确保
transition
和transform
等 CSS 属性在目标浏览器中得到广泛支持。Vue 的transition-group
组件本身没有兼容性问题,但不同的浏览器和版本可能在 CSS 动画的支持上有所不同。可以使用 CSS 前缀来增加兼容性,或使用工具(如 Autoprefixer)自动处理。
🔎7. 总结
通过这段代码,我们可以看到如何利用 Vue 3 的响应式数据和 transition-group
组件实现动态列表的过渡动画效果。无论是添加、删除还是排序元素,Vue 都能通过自动应用动画类名来平滑地展示这些变化。
- Vue 3 的优势:响应式系统和过渡动画的结合,使得动态交互和动画效果的实现变得非常简便且高效。
- CSS 动画与 Vue 结合:通过定义简单的 CSS 过渡类,我们能够为动态列表操作添加流畅的视觉效果,提升用户体验。
- 可扩展性与优化:根据实际应用需求,可以进一步扩展和优化动画效果、性能和可访问性。
这种简单而强大的动画实现方式,展示了 Vue 和 CSS 动画的有机结合,适用于许多需要动态列表或元素过渡的应用场景。