Vue中可以为元素显示隐藏添加过渡效果
显示就是元素进入(Enter)页面,隐藏就是元素离开(leave)页面
进入到离开这一整个过程,被Vue划分为两个时间段和四个时间点,并定义了对应的六个类
元素进入的过程为v-enter-active时间段,有两个时间点,v-enter为过渡开始前的状态,v-enter-to过渡结束时的状态
一言蔽之,想让元素慢慢地显示到页面上,要加过渡,v-enter用来写过渡前的样式,v-enter-to写过渡结束后的样式,v-enter-active用来定义过渡时间、运动曲线等
同理,想让元素在页面上慢慢消失,也要用过渡来实现,v-leave用来写消失前的样式,v-leave-to写消失后的样式
点击按钮,实现h3的显示和隐藏(淡入淡出效果)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="lib/vue.js"></script>
<style>
.v-enter,
.v-leave-to {
opacity: 0;
}
.v-enter-active,
.v-leave-active {
transition: all 0.5s linear;
}
</style>
</head>
<body>
<div id="app">
<input type="button" value="toggle" @click="flag = !flag">
<transition> <!--transition是Vue提供的组件,哪个元素想要实现过渡效果就要把它放在里面-->
<h3 v-if="flag">Hello</h3>
</transition>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
flag: false
}
})
</script>
</body>
</html>
对于这些在过渡中切换的类名来说,如果使用一个没有名字的 <transition>
,则 v-
是这些类名的默认前缀
如果使用了 <transition name="my-transition">
,那么 v-enter
就要替换为 my-transition-enter
如果不加name属性的话,所有元素会共用相同的样式,所以若想有单独样式,就要使用name
CSS动画用法同CSS过渡,区别是在动画中 v-enter
类名在节点插入DOM后不会立即删除,而是在 animationend
事件触发时删除,具体可查文档
使用第三方动画库Animate.css
导包,之后不需要自己写样式,直接使用Animate的类名即可
<transition enter-active-class="animated bounceIn" leave-active-class="animated bounceOut">
<h3 v-show="flag">Hello</h3>
</transition>
enter-active-class表示进入阶段使用bounceIn类样式,leave-active-class表示离开阶段使用bounceOut样式,但都要加上animated这个基本类
统一设置进入和离开的过渡时间,animated基本类可放在过渡元素中
<transition enter-active-class="bounceIn" leave-active-class="bounceOut" :duration="400">
<h3 v-show="flag" class="animated">Hello</h3>
</transition>
分别设置进入和离开的过渡时间
<transition
enter-active-class="animated bounceIn"
leave-active-class="animated bounceOut"
:duration="{enter:200,leave:300}">
<h3 v-show="flag">Hello</h3>
</transition>
半场动画
元素进入和离开为全场,只有进入没有离开的动画叫半场动画,上面两种方式无法实现半场动画,半场动画要使用JS钩子函数实现
因为CSS的过渡结束后无法自动地回到最初状态,所以要通过JS来恢复最初状态
<head>
<script src="lib/vue.js"></script>
<style>
.ball {
width: 30px;
height: 30px;
border-radius: 50%;
background: #2c323b;
}
</style>
</head>
<body>
<div id="app">
<input type="button" value="小球掉落" @click="flag = !flag">
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
>
<div class="ball" v-show="flag"></div>
</transition>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
flag: false
},
methods:{
beforeEnter(el){ //el是要执行动画的那个DOM元素
el.style.transform = 'translate(0,0)'
},
enter(el,done){
el.offsetWidth
el.style.transform = 'translate(300px,400px)'
el.style.transition = 'all 1s'
//done是afterEnter函数的引用,立即调用时为了立马隐藏el
done()
},
afterEnter(){
this.flag = !this.flag
}
}
})
</script>
</body>
列表动画
以上都是是控制单个元素的动画,如果对于一个列表,想让里面的每个li都有动画效果,就要使用transition-group元素
在实现列表过渡的时候如果需要过渡的元素是通过v-for渲染的,不能使用transition包裹,改为使用transition-group包裹即可
注意要设置:key属性
<transition-group>
组件还有一个特殊之处,不仅可以进入和离开动画,还可以改变定位
要使用这个新功能只需了解新增的 v-move
特性,它会在元素的改变定位的过程中应用
.v-move{
transition: all 0.6s ease;
}
.v-leave-active{
position: absolute;
}
v-move和position配合使用,能够实现删除某一li时后续的li渐渐飘上来的效果
给transition-group添加appear属性,可以让页面刚展示时有入场效果
页面渲染时会把transition-group渲染成一个span,这不符合w3c规范,span里最好不要放块级元素
解决方法是代码中去掉ul标签,在transition-group添加tag属性,将transition-group渲染成指定的元素
<transition appear tag="ul">
<li v-for="item in list"></li>
</transition>