首页 > 编程笔记 > JavaScript笔记
阅读:249
Vue transtion实现过渡动画效果(非常详细)
Vue 在插入、更新或者移除 DOM 时,提供了多种不同方式的应用过渡效果,包括:
为什么网页需要添加过渡和动画效果呢?因为过渡和动画效果能够提高用户的体验,帮助用户更好地理解页面中的功能。
本节重点学习用 transition 组件实现过渡和动画效果。

图 1 没有过渡效果
当单击按钮时,会发现 p 标签出现或者消失,但没有过渡效果,用户体验不太好。可以使用 Vue 的 transition 组件来实现消失或者隐藏的过渡效果。使用 Vue 过渡的时候,首先把过渡的元素添加到 transition 组件中。其中 .v-enter、.v-leave-to、.v-enter-active 和 .v-leave-active 样式是定义动画的过渡样式。
【实例】添加 CSS 过渡效果。

图 2 过渡效果
然后过渡到初始的位置,如下图所示。

图 3 显示内容
一个过渡效果包括两个阶段:一个是进入动画(Enter);另一个是离开动画(Leave)。
进入动画包括 v-enter、v-enter-to 两个时间点和 v-enter-active 一个时间段。离开动画包括 v-leave、v-leave-to 两个时间点和 v-leave-active 一个时间段。具体如下图所示:

图 4 过渡动画的时间点
定义过渡时,首先使用 transition 元素把需要被过度控制的元素包裹起来,然后自定义两组样式来控制 transition 内部的元素实现过渡。对于这些在过渡中切换的类名来说,如果使用一个没有名字的 <transition>,则 v- 是这些类名的默认前缀。
前面示例中定义的样式,在所有动画中会公用,transition 有一个 name 属性,可以通过它来修改过渡样式的名称。如果使用了 <transition name="my-transition">,那么 v-enter 会替换为 my-transition-enter。这样做的好处是区分每个不同的过渡和动画。
下面通过一个按钮来触发两个过渡效果,一个从右侧 150px 的位置开始,一个从下面 200px 的位置开始。
【实例】多个过渡效果。

图 5 多个过渡效果图
最终状态如下图所示:

图 6 最终状态
CSS动画的用法如下。

图 7 CSS动画效果
它们的优先级高于普通的类名,这对于 Vue 的过渡系统和其他第三方 CSS 动画库(如 Animate.css)的结合使用十分有用。
下面的示例在 transition 组件中使用 enter-active-class 和 leave-active-class 类,结合 animate.css 动画库实现动画效果。
【实例】自定义过渡的类名。

图 8 进入动画效果
再次单击“早春”按钮,触发离开动画,效果如图 9 所示。

图 9 离开动画效果

图 10 进入动画效果
再次单击“雪晴晚望”按钮,离开动画,效果如下图所示。

图 11 离开动画效果
Velocity 动画的配置选项如下:
- 在 CSS 过渡和动画中自动应用 class。
- 可以配合使用第三方 CSS 动画库,如 Animate.css。
- 在过渡钩子函数中使用 JavaScript 直接操作 DOM。
- 可以配合使用第三方 JavaScript 动画库,如 Velocity.js。
为什么网页需要添加过渡和动画效果呢?因为过渡和动画效果能够提高用户的体验,帮助用户更好地理解页面中的功能。
本节重点学习用 transition 组件实现过渡和动画效果。
transition组件
Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡:- 条件渲染(使用 v-if)。
- 条件展示(使用 v-show)。
- 动态组件。
- 组件根节点。
1) CSS过渡
常用的过渡都是使用 CSS 过渡。下面是一个没有使用过渡效果的示例,通过一个按钮控制 p 元素显示和隐藏。
<div id="app">
<button v-on:click="show = !show">
上京即事五首·其一
</button>
<p v-if="!show">大野连山沙作堆,白沙平处见楼台。</p>
<p v-if="!show">行人禁地避芳草,尽向曲阑斜路来。</p>
</div>
<!--引入Vue文件-->
<script src="https://unpkg.com/vue@next"></script>
<script>
//创建一个应用程序实例
const vm= Vue.createApp({
//该函数返回数据对象
data(){
return{
show:true
}
}
//在指定的DOM元素上装载应用程序实例的根组件
}).mount('#app');
</script>
在 Chrome 浏览器中运行程序,单击按钮后的效果如下图所示。
图 1 没有过渡效果
当单击按钮时,会发现 p 标签出现或者消失,但没有过渡效果,用户体验不太好。可以使用 Vue 的 transition 组件来实现消失或者隐藏的过渡效果。使用 Vue 过渡的时候,首先把过渡的元素添加到 transition 组件中。其中 .v-enter、.v-leave-to、.v-enter-active 和 .v-leave-active 样式是定义动画的过渡样式。
【实例】添加 CSS 过渡效果。
<style>
/*v-enter-active入场动画的时间段*/
/*v-leave-active离场动画的时间段*/
.v-enter-active, .v-leave-active{
transition: all .5s ease;
}
/*v-enter是一个时间点,是进入之前元素的起始状态,此时还没有进入*/
/*v-leave-to是一个时间点,是动画离开之后,离开的终止状态,此时元素动画已经结束*/
.v-enter, .v-leave-to{
opacity: 0.2;
transform:translateY(200px);
}
</style>
<div id="app">
<button v-on:click="show = !show">
古诗欣赏
</button>
<transition>
<p v-if="!show">鸿雁长飞光不度,鱼龙潜跃水成文。</p>
</transition>
</div>
<!--引入Vue文件-->
<script src="https://unpkg.com/vue@next"></script>
<script>
//创建一个应用程序实例
const vm= Vue.createApp({
//该函数返回数据对象
data(){
return{
show:true
}
}
//在指定的DOM元素上装载应用程序实例的根组件
}).mount('#app');
</script>
在 Chrome 浏览器中运行程序,单击“古诗欣赏”按钮,可以发现,p 元素刚开始在下侧 200px 的位置开始,透明度为 0.2,如下图所示:
图 2 过渡效果
然后过渡到初始的位置,如下图所示。

图 3 显示内容
2) 过渡的类名
在进入/离开的过渡中,会有 6 个 class 切换:- v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
- v-enter-to:定义进入过渡的结束状态。在元素被插入之后的下一帧生效(与此同时 v-enter 被移除),在过渡/动画完成之后移除。
- v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间、延迟和曲线函数。
- v-leave:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
- v-leave-to:定义离开过渡的结束状态。在离开过渡被触发之后的下一帧生效(与此同时v-leave被删除),在过渡/动画完成之后移除。
- v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间、延迟和曲线函数。
一个过渡效果包括两个阶段:一个是进入动画(Enter);另一个是离开动画(Leave)。
进入动画包括 v-enter、v-enter-to 两个时间点和 v-enter-active 一个时间段。离开动画包括 v-leave、v-leave-to 两个时间点和 v-leave-active 一个时间段。具体如下图所示:

图 4 过渡动画的时间点
定义过渡时,首先使用 transition 元素把需要被过度控制的元素包裹起来,然后自定义两组样式来控制 transition 内部的元素实现过渡。对于这些在过渡中切换的类名来说,如果使用一个没有名字的 <transition>,则 v- 是这些类名的默认前缀。
前面示例中定义的样式,在所有动画中会公用,transition 有一个 name 属性,可以通过它来修改过渡样式的名称。如果使用了 <transition name="my-transition">,那么 v-enter 会替换为 my-transition-enter。这样做的好处是区分每个不同的过渡和动画。
下面通过一个按钮来触发两个过渡效果,一个从右侧 150px 的位置开始,一个从下面 200px 的位置开始。
【实例】多个过渡效果。
<style>
.v-enter-active, .v-leave-active {
transition: all 0.5s ease;
}
.v-enter, .v-leave-to{
opacity: 0.2;
transform:translateX(150px);
}
.my-transition-enter-active, .my-transition-leave-active {
transition: all 0.8s ease;
}
.my-transition-enter, .my-transition-leave-to{
opacity: 0.2;
transform:translateY(200px);
}
</style>
<div id="app">
<button v-on:click="show = !show">
出郊
</button>
<transition>
<p v-if="!show">高田如楼梯,平田如棋局。</p>
</transition>
<transition name="my-transition">
<p v-if="!show">白鹭忽飞来,点破秧针绿。</p>
</transition>
</div>
<!--引入Vue文件-->
<script src="https://unpkg.com/vue@next"></script>
<script>
//创建一个应用程序实例
const vm= Vue.createApp({
//该函数返回数据对象
data(){
return{
show:true
}
}
//在指定的DOM元素上装载应用程序实例的根组件
}).mount('#app');
</script>
在 Chrome 浏览器中运行程序,单击“出郊”按钮,触发两个过渡效果,如下图所示:
图 5 多个过渡效果图
最终状态如下图所示:

图 6 最终状态
3) CSS动画
CSS 动画的用法与 CSS 过渡差不多,区别是在动画中,v-enter 类名在节点插入 DOM 后不会立即删除,而是在 animationend 事件触发时删除。CSS动画的用法如下。
<style>
/*进入动画阶段*/
.my-enter-active {
animation: my-in .5s;
}
/*离开动画阶段*/
.my-leave-active {
animation: my-in .5s reverse;
}
/*定义动画my-in*/
@keyframes my-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
</style>
<div id="app">
<button @click="show = !show">对雪</button>
<transition name="my">
<p v-if="show">六出飞花入户时,坐看青竹变琼枝。如今好上高楼望,盖尽人间恶路岐。</p>
</transition>
</div>
<!--引入Vue文件-->
<script src="https://unpkg.com/vue@next"></script>
<script>
//创建一个应用程序实例
const vm= Vue.createApp({
//该函数返回数据对象
data(){
return{
show:true
}
}
//在指定的DOM元素上装载应用程序实例的根组件
}).mount('#app');
</script>
在 Chrome 浏览器中运行程序,单击“对雪”按钮时,触发 CSS 动画,效果如下图所示:
图 7 CSS动画效果
4) 自定义过渡的类名
可以通过以下 attribute 来自定义过渡的类名:- enter-class。
- enter-active-class。
- enter-to-class。
- leave-class。
- leave-active-class。
- leave-to-class。
它们的优先级高于普通的类名,这对于 Vue 的过渡系统和其他第三方 CSS 动画库(如 Animate.css)的结合使用十分有用。
下面的示例在 transition 组件中使用 enter-active-class 和 leave-active-class 类,结合 animate.css 动画库实现动画效果。
【实例】自定义过渡的类名。
<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet"
type="text/css">
<div id="app">
<button @click="show = !show">
早春
</button>
<!--enter-active-class:控制动画的进入-->
<!--leave-active-class:控制动画的离开-->
<!--animated 类似于全局变量,它定义了动画的持续时间-->
<!--bounceInUp和slideInRight是动画具体的动画效果的名称,可以选择任意的效果-->
<transition
enter-active-class="animated bounceInUp"
leave-active-class="animated slideInRight"
>
<p v-if="show">春销不得处,唯有鬓边霜。</p>
</transition>
</div>
<!--引入Vue文件-->
<script src="https://unpkg.com/vue@next"></script>
<script>
//创建一个应用程序实例
const vm= Vue.createApp({
//该函数返回数据对象
data(){
return{
show:true
}
}
//在指定的DOM元素上装载应用程序实例的根组件
}).mount('#app');
</script>
在浏览器运行,单击“早春”按钮,触发进入动画,效果如下图所示:
图 8 进入动画效果
再次单击“早春”按钮,触发离开动画,效果如图 9 所示。

图 9 离开动画效果
5) 动画的JavaScript钩子函数
可以在 <transition> 组件中声明 JavaScript 钩子,它以属性的形式存在。例如下面的代码:
<transition
进入动画钩子函数
:before-enter表示动画入场之前,此时动画还未开始,可以在其中设置元素开始动画之前的起始样式
v-on:before-enter="beforeEnter"
:enter表示动画,开始之后的样式,可以设置完成动画的结束状态
v-on:enter="enter"
:after-enter表示动画完成之后的状态
v-on:after-enter="afterEnter"
:enter-cancelled用于取消开始动画的
v-on:enter-cancelled="enterCancelled"
离开动画钩子函数,离开动画和进入动画钩子函数说明类似
v-on:before-leave="beforeLeave"
v-on:leave="leave"
v-on:after-leave="afterLeave"
v-on:leave-cancelled="leaveCancelled"
>
<!-- ... -->
</transition>
然后在 Vue 实例的 methods 选项中定义钩子函数的方法:
<script>
//创建一个应用程序实例
const vm= Vue.createApp({
//该函数返回数据对象
data(){
return{
show:true
}
},
methods: {
// 进入中
beforeEnter: function (el) {
...
},
// 当与 CSS 结合使用时
// 回调函数 done 是可选的
enter: function (el, done) {
...
done()
},
afterEnter: function (el) {
...
},
enterCancelled: function (el) {
...
},
// 离开时
beforeLeave: function (el) {
...
},
// 当与 CSS 结合使用时
// 回调函数 done 是可选的
leave: function (el, done) {
...
done()
},
afterLeave: function (el) {
...
},
// leaveCancelled 只用于 v-show 中
leaveCancelled: function (el) {
...
}
//在指定的DOM元素上装载应用程序实例的根组件
}).mount('#app');
</script>
这些钩子函数可以结合 CSS transitions/animations 使用,也可以单独使用。
下面使用 velocity.js 动画库结合动画钩子函数来实现一个简单示例。当只用 JavaScript 过渡的时候,在 enter 和 leave 中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成。对于仅使用 JavaScript 过渡的元素,推荐添加 v-bind:css="false",Vue 会跳过 CSS 的检测。这也可以避免过渡过程中 CSS 的影响。
<!--Velocity和jQuery.animate 的工作方式类似,也是用来实现JavaScript动画的一个很棒的选择
-->
<script src="velocity.js"></script>
<div id="app">
<button @click="show = !show">
雪晴晚望
</button>
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:leave="leave"
v-bind:css="false"
>
<p v-if="show">
野火烧冈草,断烟生石松。
</p>
</transition>
</div>
<!--引入Vue文件-->
<script src="https://unpkg.com/vue@next"></script>
<script>
//创建一个应用程序实例
const vm= Vue.createApp({
//该函数返回数据对象
data(){
return{
show:false
}
},
methods: {
// 进入动画之前的样式
beforeEnter: function (el) {
// 注意:动画钩子函数的第一个参数:el,表示要执行动画的那个DOM元素,
// 是一个原生的JS DOM对象
// 可以认为,el是通过document.getElementById('')方式获取到原生JS DOM对象的
el.style.opacity = 0;
el.style.transformOrigin = 'left';
},
// 进入时的动画
enter: function (el, done) {
Velocity(el, { opacity: 1, fontSize: '2em' }, { duration: 300 });
Velocity(el, { fontSize: '1em' }, { complete: done });
},
//离开时的动画
leave: function (el, done) {
Velocity(el, { translateX: '15px', rotateZ: '50deg' }, { duration:
600 });
Velocity(el, { rotateZ: '100deg' }, { loop: 5 });
Velocity(el, {
rotateZ: '45deg',
translateY: '30px',
translateX: '30px',
opacity: 0
}, { complete: done })
}
}
//在指定的DOM元素上装载应用程序实例的根组件
}).mount('#app');
</script>
在 Chrome 浏览器中运行程序,单击“雪晴晚望”按钮,进入动画,效果如下图所示:
图 10 进入动画效果
再次单击“雪晴晚望”按钮,离开动画,效果如下图所示。

图 11 离开动画效果
Velocity 动画的配置选项如下:
duration:400, //动画执行时间 easing: "swing", //缓动效果 queue: "", //队列 begin:undefined, //动画开始时的回调函数 progress: undefined, //动画执行中的回调函数(该函数会随着动画的执行不断被触发) complete: undefined, //动画结束时的回调函数 display: undefined, //动画结束时设置元素的css display属性 visibility: undefined, //动画结束时设置元素的css visibility属性 loop: false, //循环次数 delay: false, //延迟 mobileHA: true //移动端硬件加速(默认开启)
ICP备案:
公安联网备案: