过渡与动画
# transition过渡组件
Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡效果:
①条件渲染 (使用 v-if)。
②条件展示 (使用 v-show)。
③动态组件。
④组件根节点。
# CSS过渡与动画
在使用CSS过渡与动画时需要配合过渡的类名来实现,在进入/离开的过渡中,会有 6 个 class 切换。
1.v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
2.v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
3.v-enter-to:2.1.8 版及以上定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。
4.v-leave:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
5.v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
6.v-leave-to:2.1.8 版及以上定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。
# 进入/离开的过渡流程图:
# 1.CSS过渡
<style>
[v-cloak]{
display:none;
}
/*进入时过渡时的开始状态*/
.slide-fade-enter{
transform: translateX(0px);
}
/*进入过渡生效时的状态*/
.slide-fade-enter-active {
transition: all .3s ease;
}
/*离开过渡生效时的状态*/
.slide-fade-leave-active {
transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
/*离开过渡时的结束状态*/
.slide-fade-leave-to{
transform: translateX(200px);
}
.box{width:100px;height:100px;background-color:#0000FF;font-size:14px;color:#EFEFEF}
</style>
//app组件
let APPComponent={
template:`
<div>
<button @click="show = !show">
Toggle render
</button>
<transition name="slide-fade">
<div class="box" v-if="show">hello</div>
</transition>
</div>
`,
data(){
return {
show:true
}
},
};
};
new Vue({
el:"#app",
template:`
<APPComponent></APPComponent>
`,
components:{
APPComponent
}
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# 2.CSS动画
CSS动画用法同CSS过渡,区别是在动画中v-enter类名在节点插入 DOM 后不会立即删除,而是在animationend(动画结束)事件触发时删除。代码如下:
<style>
[v-cloak]{
display:none;
}
/*进入过渡生效时的状态*/
.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);
}
}
.box{width:100px;height:100px;background-color:#0000FF;font-size:14px;color:#EFEFEF}
</style>
let APPComponent={
template:`
<div>
<button @click="show = !show">
Toggle render
</button>
<transition name="bounce">
<div class="box" v-show="show">hello</div>
</transition>
</div>
`,
data(){
return {
show:true
}
},
};
new Vue({
el:"#app",
template:`
<APPComponent></APPComponent>
`,
components:{
APPComponent
}
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# 多个元素的过渡
如果<transition>
组件内部有多个元素可以使用 v-if/v-else进行过渡,来确保最终内部只有一个元素,可以实现多标签切换动画效果。代码如下:
<style>
/*进入过渡时的开始状态*/
.slide-fade-enter{
transform: translateX(100px);
opacity: 1;
}
/*进入/离开过渡生效时的状态*/
.slide-fade-enter-active,.slide-fade-leave-active {
transition: all .3s ease;
}
/*离开过渡时的结束状态*/
.slide-fade-leave-to{
transform: translateX(0px);
opacity: 0;
}
</style>
template:`
<div>
<transition name="slide-fade" mode="out-in">
<button v-if="show" key="save" @click="show=!show">
Save
</button>
<button v-else key="edit" @click="show=!show">
Edit
</button>
</transition>
</div>
`,
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
使用v-if/v-else可以实现两个按钮切换的动画效果。当有相同标签名的元素切换时,需要通过key属性设置唯一的值来标记以让 Vue 区分它们,否则 Vue 为了效率只会替换相同标签内部的内容。即使在技术上没有必要,给在<transition>
组件中的多个元素设置 key 是一个更好的选择。注意一下在<transition>
组件有一个mode属性,这个是过渡模式,可以让<transition>
组件内部元素运动像滑动过渡。mode属性有两个值分别是:
1.in-out:新元素先进行过渡,完成之后当前元素过渡离开。
2.out-in:当前元素先进行过渡,完成之后新元素过渡进入。
# 多个组件的过渡
多个组件的过渡简单很多,不需要使用key属性。只需要使用动态组件即可。
# 配合animate.css实现动画效果
Vue的过渡系统可以和其他第三方CSS动画库结合使用,比如Animate.css(官网:https://daneden.github.io/animate.css/)这时我们需要自定义过渡的类名才能实现,可以通过以下 attribute 来自定义过渡类名:
lenter-class:进入过渡时的开始状态
lenter-active-class:进入过渡生效时的状态。
lenter-to-class (2.1.8+):进入过渡的结束状态。
lleave-class:离开过渡的开始状态。
lleave-active-class:离开过渡生效时的状态。
lleave-to-class (2.1.8+):离开过渡的结束状态。
<!--引入animate.css样式-->
<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css">
<style>
[v-cloak]{
display:none;
}
.box{width:100px;height:100px;background-color:#0000FF;font-size:14px;color:#EFEFEF;}
<style>
new Vue({
el:"#app",
data(){
return {
show:false
}
},
template:`
<div>
<transition enter-active-class="animated slideInLeft" leave-active-class="animated slideInRight">
<div class="box" v-show="show"></div>
</transition>
<button @click="show=!show">go</button>
</div>
`
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# css过渡 demo
See the Pen vue的过渡动画 by xugaoyi (@xugaoyi) on CodePen.
# css动画 demo
See the Pen vue的动画 by xugaoyi (@xugaoyi) on CodePen.
# 组件中使用的示例
<template>
<transition name="slide">
<div class="add-song">
...
</div>
</transition>
<template>
2
3
4
5
6
7
.add-song
&.slide-enter-active, &.slide-leave-active
transition: all 0.3s
&.slide-enter, &.slide-leave-to
transform: translate3d(100%, 0, 0)
2
3
4
5
# animate.css的Demo
See the Pen vue中使用animate.css库 by xugaoyi (@xugaoyi) on CodePen.
# transition-group列表过渡
# 列表的进入/离开过渡
<transition-group tag="ul"> <!--tag转为ul-->
<li v-for="item in list" :key="item">{{item}}</li> <!--子元素要有key-->
</transition-group>
2
3
注意:列表元素一定要有key
.v-enter,.v-leave-to{
opacity: 0;
transform: translateX(30px);
}
.v-enter-active,.v-leave-active{
transition: all 1s;
}
2
3
4
5
6
7
See the Pen vue列表过渡 by xugaoyi (@xugaoyi) on CodePen.
# 列表的排序过渡
.v-move {
transition: transform 1s;
}
2
3
See the Pen vue列表过渡-排序过渡 by xugaoyi (@xugaoyi) on CodePen.
列表过渡&排序过渡
See the Pen vue列表过渡&排序过渡 by xugaoyi (@xugaoyi) on CodePen.