Vue中过渡和动画
在Vue中使用动画时,经常是一知半解,有时候加上动画不知道为什么不执行,有时候设置的动画与我们想象中不太一样。因此,通过本篇文章对Vue中的动画做了一次详细的学习,本文内容全部来自Vue官方文档。
概述
过渡/动画的适用条件
我们想要使用过渡和动画,首先需要了解什么情况下能够使用动画,Vue在插入、更新或者删除DOM时,提供了多种不同方式的过渡效果,通常是使用v-if、v-show和动态组件的情况下。也就是说我们只有在这几种情况下设置过渡动画才有效果,这就是为什么我们有时候设置过渡动画无效的原因之一。
有哪些常见的过渡/动画实现方式 Vue中过渡/动画主要包括单元素/组件的过渡,多元素/组件的过渡和列表的过渡。每种过渡都有对应的实现方式,接下来我们一一介绍这些实现。
单元素/组件的过渡和动画
1. css transition
Vue提供了transition的封装组件,具体使用方法如下:
给需要设置过渡的元素作为 transition
的子元素给 transition
加上name
属性,会自动应用6个class
。通过这些class
的切换,实现过渡效果。想要实现过渡效果,必须合理地设置class的值。其中过渡必须有初始值,然后对应的css中有新的值。
.show-enter-active, .show-leave-active {
transition: all 3s;
}
.show-enter, .show-leave-to {
opacity: 0;
width:300px; // 新的值
}
p{
border:1px solid red;
width:100px; // 初始值
}
6个class
transition
在应用过渡的过程中通过class
的切换来实现过渡效果,其中主要包括:
进入过渡:v-enter
,v-enter-active
和v-enter-to
3个class。
离开过渡:v-leave
,v-leave-active
和v-leave-to
3个class。
在元素从隐藏到显示会触发进入过渡的3个class的切换,但是不会触发离开过渡的3个class的切换。
在元素从显示到隐藏会触发离开过渡的3个class的切换,但是不会触发进入过渡的3个class的切换。
v-enter:实际上就是动画的第一帧。
p{
border:1px solid red;
width:100px;
background:black;
}
.show-enter{
background:red;
}
这里show-enter表示进入动画的第一帧元素背景是红色。
v-enter-active:表示进入动画的过程,用来描述动画的执行,比如执行多少秒,哪些属性执行,类似于CSS3中的transition。这是每个动画都必须有的。
.show-enter-active{
transition: all 3s;
}
表示所有的属性进入动画后执行3s。
v-enter-to:定义进入动画过渡的结束状态,也就是进入动画的最后一帧。通常是变成元素正常展示的状态。
.show-enter-to{
background:black;
}
一般是不需要设置v-enter-to。一般v-enter-to就是元素默认的样式。
这三个类的添加和移除顺序为:
第一帧:添加v-enter
和 v-enter-active
两个class
第二帧:v-enter
被移除,添加v-enter-to
这个class。这时候有v-enter-active
和v-enter-to
两个class。
最后动画过渡结束,移除v-enter
和v-enter-to
类。
注意这几个class只有在元素插入时才有,也就是在DOM结构中插入一个新的元素时才有(比如v-if = true的时候)。如果是从DOM结构中删除元素并不会有这三个class。也就是说我们要理解过渡的执行,并不是所有的动画都需要6个class,如果你只是想在
显示元素时假如过渡,那么你只需要设置v-enter
,v-enter-active
和v-enter-to
就可以了。
v-leave:动画离开时的第一帧,一般不需要设置,默认为当前的样式。
v-leave-active::定义离开过渡动画的过程,用来描述动画的离开过程。通常也是用来设置过渡时间,延迟和曲线函数等。
.show-leave-active {
transition: all 10s;
}
v-leave-to:定义动画结束时的样式。也是过渡的最后一帧的状态。
总结:6个class,通常只需要设置4个。v-enter
和v-enter-active
(其中v-enter-to
是元素展示时的默认样式)。v-leave-active
和v-leave-to
(其中v-leave
是元素隐藏时的默认样式)。而且,通常进入动画和离开动画的过程一致,因此,最终的设置通常如下:
.show-enter-active, .show-leave-active {
transition: opacity .5s;
}
.show-enter, .show-leave-to{
opacity: 0;
}
2. css animation
vue中animation动画的实现跟CSS3差不多。只不过这里是通过v-enter-active
和v-leave-active
来实现。
我们只需要确保两件事:
定义 v-enter-active
和v-leave-active
这两个class。不同于transition,我们不需要定义v-ente
r和v-leave-to
这两个class。定义一个@keyframes动画。 确保正常动画100%时元素处于正常状态(特殊设计的动画效果除外)。
.bounce-enter-active {
animation: bounce-in .5s;
}
.bounce-leave-active {
animation: bounce-in .5s reverse;
}
/* 通过定义一个动画。然后直接设置动画的过程就可以了。 */
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
/* 通常要确保最后结束的状态是正常状态 */
transform: scale(1);
}
}
3. 使用自定义过渡类名配合第三方库来做过渡/动画
通常情况下,我们自己写的过渡效果可能不太酷炫,这时候我们希望能够引入一些第三方库的动画效果。Vue提供了以下自定义类名来配合第三方库实现动画。
enter-class enter-active-class enter-to-class leave-class leave-active-class leave-to-class 他们的优先级高于普通的类名。我们可以使用第三方库animate.css中的类名来作为transition中的自定义类名,从而借助一些第三方库实现一些酷炫的动画效果。
<div id="example-3">
<button @click="show = !show">
Toggle render
</button>
<transition
enter-active-class="animated shake"
leave-active-class="animated bounceOutRight"
>
<p v-if="show">hello</p>
</transition>
</div>
上面的代码中,我们通过设置enter-active-class的类名为animated shake从而调用了animate.css中的shake类实现的过渡效果。
4. Javascript钩子实现过渡/动画
一些情况下,我们希望通过js来实现过渡/动画,而不是仅仅通过css来实现。Vue提供了一些钩子,通过这些钩子可以方便我们操作js来实现过渡效果。
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
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>
这些钩子通常也是配合一些js动画库来实现动画效果。
多元素/多组件的过渡
1. 多元素的过渡
我们现在有两个button,我们希望通过点击on时,切换为off button。点击off时,切换为on button,这里就涉及到多个元素(button)的过渡了,一个需要显示出来,一个需要隐藏起来。 html结构如下:
<transition name = "fade">
<button v-if = "status === 'off'" @click = "status='on'">on</button>
<button v-else @click = "status='off'" >off</button>
</transition>
css如下:
.fade-enter-active,.fade-leave-active{
transition: all 1s;
}
.fade-enter{
opacity:0;
background:red;
}
.fade-leave-to{
opacity:0;
background:red;
}
这里会出现两个问题:
多个元素可能会被vue识别为同一个元素,比如上文中的button由于只是内部文本的不同,切换时会被Vue只是识别成一个元素,只是内容的展示不同。但是实际上我们是要实现两个元素的过渡,因此为了避免这种情况,我们需要给每个过渡的元素设置不同的key值。 Vue中多个元素的进入和离开的过渡同时发生的,这样的话会导致一些问题,比如隐藏的元素动画执行时间长,会占据需要显示的元素位置,影响动画效果,因此,我们希望多个元素能够按照先后顺序进行过渡,比如先隐藏再显示。Vue动画中提供了 mode
模式来设置控制多个元素的过渡。
<transition name = "fade" mode="out-in">
<button key = "on" v-if = "status === 'off'" @click = "status='on'">on</button>
<button key = "off" v-else @click = "status='off'" >off</button>
</transition>
mode="out-in"表示先执行离开的过渡,然后执行进入的过渡。
总结:
多个元素的过渡必须使用key来进行区分,需要设置mode来控制过渡模式。
2. 多组件的过渡
多组件的切换不需要使用key,可以通过使用component动态组件来实现。
<transition name="component-fade" mode="out-in">
<component v-bind:is="view"></component>
</transition>
列表的过渡
目前为止,关于过渡我们已经讲到:
单个节点 同一时间渲染多个节点中的一个 我们之前说过在插入DOM,删除DOM和更新DOM时可以使用过渡,而列表也适用这种情况。列表是要在同一时间渲染多个DOM。在这种场景中,Vue提供了 <transition-group>
组件:
<div id="list-demo" class="demo">
<button v-on:click="add">Add</button>
<button v-on:click="remove">Remove</button>
<transition-group name="list" tag="p">
<span v-for="item in items" v-bind:key="item" class="list-item">
</span>
</transition-group>
</div>
列表的过渡:
必须使用 transition-group
标签。不同于<transition>
,它会以一个真实元素呈现:默认为一个<span>
。你也可以通过tag
属性更换为其他元素。循环的列表必须是 transition-group
的第一个子元素,中间不能有其他元素,否则无法生效。列表内部元素必须提供唯一的 key
值。CSS 过渡的类将会应用在内部的元素中,而不是这个组/容器本身。css的过渡与之前的 transition
过渡写法相同。
总结
本文主要讲述了Vue中过渡/动画的使用,主要包括过渡的使用条件,单元素/组件的4中过渡/动画的实现方式,多元素/多组件的过渡实现方式以及列表的的过渡。虽然都是Vue中的一些基础API,但是了解了这些,才能够在开发过程中帮助我们更好地应用动画,从而实现一些酷炫的效果。
本文使用 mdnice 排版