Vue中的动画并不是是指利用Vue实现某些炫酷的效果,而是通过某些的过渡类名在插入、更新或者移除 DOM 时元素添加过渡效果,使其看上去不那么生硬。
Vue中主要有以下几个过渡类名
v-enter
:元素动画为开始元素初始状态
v-enter-active
:定义动画入场状态,在整个过渡阶段应用,这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
v-enter-to
:定义动画进入过渡结束状态
v-leave
:定义离开过渡的开始状态。在离开过渡被触发时立刻生效。
v-leave-active
:定义动画离场状态,在整个过渡阶段应用,这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
v-leave-to
:定义动画离开过渡结束状态
1.定义过渡类名
2.将要实现的动画的元素用transition
或transition-group
包裹起来,他们的区别下文提及
3.移除或更新DOM实现动画
示例
HTML结构
<div id='app'>
<button @click="flag!=flag">添加</button>
<!-- 点击按钮使h3显示,再次点击h3隐藏 -->
<!-- 使用 transition元素把需要被动画控制的元素包裹起来 -->
<!-- 自定义两组样式控制transtion 内部的元素实现动画 -->
<transition">
<h3 v-if="flag"></h3>
</transition>
</div>
CSS样式
.v-enter,
.v-leave-to{
opacity: 0;
transform: translateX(140px);
}
.v-enter-active,
.v-leave-active{
transition:all .5s
}
VM
var vm = new Vue({
el:"#app",
data:{
flag:false
}
})
可以看到我们自定义过渡类名后vue在DOM更新时自动添加了动画
动画前缀
Vue中动画默认前缀是v-
我们也可以自定义前缀,只需在transition
标签中加入name
属性并赋值前缀名即可,这在后面要讲到的利用animate.css实现动画将非常有用。
半场动画
不知道你有没有看到这种效果。
类似于上面的效果称之为半场动画,因为元素只有“进入动画”,并没有向第一个示例那样一进一出,如某app的购物车动画实现,这种半场动画必须借助与动画钩子函数来实现。 常用的动画钩子函数 before-enter
:元素初始状态 enter
:动画开始之后的样式,定义动画执行时间,设置元素完成动画之后的结束状态 after-enter
:动画结束 ...更多请参照官网文档
半场动画步骤
1.在transition
中绑定动画钩子函数
2.在methods中定义动画钩子函数,在钩子函数里面操作DOM设置元素过渡时间
示例实现小球半场动画
HTML
<div id='app'>
<button @click="flag!flag">点击</button>
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
>
<div class='bar' v-if='flag'></div>
</transition>
</div>
CSS
.v-enter,
.v-leave-to{
opacity: 0;
transform: translateX(140px);
}
.v-enter-active,
.v-leave-active{
transition:all .5s
}
.bar{
width:20px;
height:20px;
border-radis:50%;
background:red
}
VM
var vm = new Vue({
el:"#app",
data:{
flag:false
},
methods:{
beforeEnter:function(el){
el.style.transform="translate(0,0)"
},
enter:function(el,done){
el.offsetWidth;//没有实际作用,不写没有动画效果 强制动画刷新
el.style.transform="translate(140px,200px)"
el.style.transition="all .5s"
done()
},
afterEnter:function(this.flag=false)
}
}
})
在官方文档有这样一句话
当只用 JavaScript 过渡的时候,在 enter 和 leave 中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成。
可以看到钩子函数enter
我调用了done()
这个函数相当于调用了afterEnter
钩子函数
动画组
有时候我们的DOM元素并不是写死,而是经过循环渲染出来,这个时候我们要给这些被循环渲染出来的元素添加动画就必须使用动画组transition-group
因为transition
只适用于单个元素,同时在使用v-for
时还必须给元素添加key
属性。
示例 点击li移除当前元素
HTML
<div id='app'>
<transition-group tag="ul">
<li v-for="(item,i) in list" :key="item.id" @click="del(i)">{{item.name}}</li>
</transition-group>
</div>
CSS
ul li{
padding:20px;
border:1px dashed #ddd;
}
.v-enter,
.v-leave-to{
opacity: 0;
transform: translateY(80px);
}
.v-enter-active,
.v-leave-active{
transition:all .5s ease
}
VM
var vm = new Vue({
el:"#app",
data:{
flag:false,
list:[
{"id":1,name:"曹操"},
{"id":2,name:"刘备"},
{"id":3,name:"周瑜"},
{"id":4,name:"诸葛亮"},
{"id":5,name:"司马懿"},
]
},
methods:{
del(id){
this.list.splice(id,1)
}
}
})
配合animate.css
我们可以配合animate.css实现动画效果而不用自定义动画
1.下载vue2-animate.css github 演示地址
2.在transition
或transition-group
添加name属性并赋值animate的css样式
示例
<div id='app'>
<transition-group name="bounce" tag="ul">
<li v-for="(item,i) in list" :key="item.id" @click="del(i)">{{item.name}}</li>
</transition-group>
</div>
<script>
var vm = new Vue({
el:"#app",
data:{
flag:false,
list:[
{"id":1,name:"曹操"},
{"id":2,name:"刘备"},
{"id":3,name:"周瑜"},
{"id":4,name:"诸葛亮"},
{"id":5,name:"司马懿"},
]
},
methods:{
del(id){
this.list.splice(id,1)
}
}
})
</script>