vue在插入、更新或者移除DOM时,提供了多种不同方式的应用过渡效果,下面主要总结一些常用的过渡。
单元素过渡(vue1.0)
我们常用的动画是css3的动画,在vue中依旧有效。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="bower_components/vue/dist/vue.js"></script> <style> #div1{ width:100px; height:100px; background: red; } .fade-transition{ transition: 1s all ease; } .fade-enter{ opacity: 0; } .fade-leave{ opacity: 0; transform: translateX(200px); } </style> </head> <body> <div id="box"> <input type="button" value="按钮" @click="toggle"> <div id="div1" v-show="bSign" transition="fade"></div> </div> <script> new Vue({ el:'#box', data:{ bSign:true }, methods:{ toggle(){ this.bSign=!this.bSign; } } }); </script> </body> </html>
在上面的例子中,我们实现了一个进入和离开的动画效果,我们需要做如下几步:
- 在需要使用动画的元素中添加名称,即上面的div中添加transition="fade"
- 根据添加的名称为元素添加class类实现动画效果,这些类必须以上一步总的名称开头
- 借用v-show进行条件展示
- 通过事件触发动画
过渡组件(vue2.0)
除了上面为元素添加动画名称的方式实现过渡外,vue还提供了transition的封装组件,在下列情况中,可以黑任何元素和组件添加进入或离开的过渡效果:
- 条件渲染(v-if)
- 条件展示(v-for)
- 动态组件
- 组件跟节点
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <script src="bower_components/vue/dist/vue.js"></script> <style> .fade-enter-active, .fade-leave-active { transition: opacity .5s; } .fade-enter, .fade-leave-to { opacity: 0; } </style> </head> <body> <div id="box"> <button v-on:click="show = !show">Toggle</button> <transition name="fade"> <p v-if="show">hello</p> </transition> </div> <script> new Vue({ el:'#box', data: { show: true } }); </script> </body> </html>
在上面的例子中,我们将需要实现动画效果的元素包裹在transition组件中,vue会自动嗅探目标元素是否应用了css过渡或动画,如果是,则会在恰当的时机添加或删除css类名。
过渡组件类名
vue在进入/离开的过渡中提供了6个可供选择的class切换,下面的例子我们只使用到了4个,关于6个类名的使用,在官方文档中详细说明。
- fade-enter:初始状态
- fade-enter-active:元素显示出来的状态(变化成什么样子)
- fade-leave:同fade-enter
- fade-leave-active:元素消失离开的状态
<!DOCTYPE html> <html lang="en"> <head> <title>vue</title> <style> p{ width:300px; height:300px; background: red; } .fade-enter-active, .fade-leave-active{ transition: 1s all ease; } .fade-enter-active{ opacity:1; width:300px; height:300px; } .fade-leave-active{ opacity:0; width:100px; height:100px; } .fade-enter,.fade-leave{ opacity:0; width:100px; height:100px; } </style> <script src="vue.js"></script> <script> window.onload=function(){ new Vue({ el:'#box', data:{ show:false } }); }; </script> </head> <body> <div id="box"> <input type="button" value="点击显示隐藏" @click="show=!show"> <transition name="fade"> <p v-show="show"></p> </transition> </div> </body> </html>
需要说明的是,因为我们在transition组件中为此组件添加了一个名称name="fade",所以我们的类名都是以该名称开头的,同上一个例子一样需要保持一致,但是这个组件名称不是必须的,所以我们也可以不用为组件添加名称,那么此时的类名就需要以v-开头,即上面的.fade-enter就需要换成v-enter了。
过渡组件相关函数
在使用过渡组件实现动画时,为了能更好的实现想要的动画效果,vue2.0中针对动画的不同状态给出了不同的动画函数,并且每个函数都接收一个代表当前运动元素的参数。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <style> p{ width:200px; height:200px; background: red; } .fade-enter-active, .fade-leave-active{ transition: 1s all ease; } .fade-enter-active{ opacity:1; width:200px; height:200px; } .fade-leave-active{ opacity:0; width:100px; height:100px; } .fade-enter,.fade-leave{ opacity:0; width:100px; height:100px; } </style> <script src="vue.js"></script> <script> window.onload=function(){ new Vue({ el:'#box', data:{ show:false }, methods:{ beforeEnter(el){ console.log('动画enter之前'); }, enter(el){ console.log('动画enter进入'); }, afterEnter(el){ console.log('动画进入之后'); el.style.background='blue'; }, beforeLeave(el){ console.log('动画leave之前'); }, leave(el){ console.log('动画leave'); }, afterLeave(el){ console.log('动画leave之后'); el.style.background='red'; } } }); }; </script> </head> <body> <div id="box"> <input type="button" value="点击显示隐藏" @click="show=!show"> <transition name="fade" @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter" @before-leave="beforeLeave" @leave="leave" @after-leave="afterLeave" > <p v-show="show"></p> </transition> </div> </body> </html>
过渡组件之多个元素
和单一的过渡组件不同的是,多个元素的过渡组件使用的是transition-group,并且需要给组件内的多个元素添加一个key用作标识符,如下所示:
但是更多的时候,这个key是循环出来的。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <style> p{ width:80px; height:30px; background: red; margin:10px auto; text-align: center; } </style> <script src="vue.js"></script> <link rel="stylesheet" href="animate.css"> </head> <body> <div id="box"> <input type="text" v-model="show"> <transition-group enter-active-class="zoomInLeft" leave-active-class="zoomOutRight"> <p v-show="show" class="animated" v-for="(val,index) in lists" :key="index"> {{val}} </p> </transition-group> </div> <script> new Vue({ el:'#box', data:{ show:'', list:['apple','banana','orange','pear'] }, computed:{ lists:function(){ var arr=[]; this.list.forEach(function(val){ if(val.indexOf(this.show)!=-1){ arr.push(val); } }.bind(this)); return arr; } } }); </script> </body> </html>
css动画库
Animate.css是一款常见的动画库,在html中经常被使用,我们在vue1.0中依旧可以通过引用的方式使用。
在使用第三方动画库的时候,我们还是和上面的例子一样通过添加类名来实现动画,只是这里的类名不再是我们自己写的类,而是直接使用第三库中的类名,这里稍微做了一点改变的是,我们是在vue中添加了一个transitions,然后将所有的动画名称集中写在了这个里面而已。
首先需要为元素添加一个class类为: class="animated",然后再添加动画名称transition="bounce",最后根据动画名称进行定义相关动画类。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="bower_components/vue/dist/vue.js"></script> <link rel="stylesheet" href="bower_components/animate.css/animate.css"> <style> #box{ width:400px; margin: 0 auto; } #div1{ width:100px; height:100px; background: red; } </style> </head> <body> <div id="box"> <input type="button" value="按钮" @click="toggle"> <div id="div1" class="animated" v-show="bSign" transition="bounce"></div> </div> <script> new Vue({ el:'#box', data:{ bSign:true }, methods:{ toggle(){ this.bSign=!this.bSign; } }, transitions:{ //定义所有动画名称 bounce:{ enterClass:'zoomInLeft', leaveClass:'zoomOutRight' } } }); </script> </body> </html>
但是在vue2.0中,使用上稍微有点不同,具体的有两种实现方式,分别如下所示: