Vue 在插入、更新或者移除 DOM 时,提供多种不一样方式的应用过渡效果。
包括如下工具:css
下面分别从这个4个工具来学习Vue动画效果。html
Vue 提供了 transition
的封装组件,在下列情形中,能够给任何元素和组件添加进入/离开过渡vue
v-if
)v-show
)一个典型的例子:git
Html文件github
<div id="app"> <transition name="fade"> <div v-if="show"> Hello world. </div> </transition> <button @click="handleClick">切换</button> </div>
js文件浏览器
<script> // 1. 建立Vue的实例 let vm = new Vue({ el:'#app', data:{ show:false }, methods:{ handleClick:function(){ this.show = !this.show } } }); </script>
css文件app
<style> .fade-enter-active, .fade-leave-active { transition: opacity 2s; } .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ { opacity: 0; } </style>
这个例子的效果为:点击切换,文字会淡入淡出。ide
实现原理:函数
一、经过使用transition组件后, Vue 将会作如下处理:工具
nextTick
概念不一样)二、动画进入时,Vue会添加CSS类,若是没有使用name="fade"的话,类名为v-fade-enter、v-fade-eneter-active等。
第一帧动画,会自动添加fade-enter和fade-enter-active类
第二帧动画,会去掉fade-enter类,添加fade-enter-to类
第三帧动画,会去掉全部enter类
三、动画在离开时一样会添加或删除CSS类
一、使用自定义类
效果为:进入或离开都会有拉升效果。
注意:这里咱们使用了
name="bounce"替换了默认的fade。固然,若是没有fade的话,也会有v-做为默认开头。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> @keyframes bounce-in { 0% { transform: scale(0); } 50% { transform: scale(1.5); } 100% { transform: scale(1); } } .bounce-enter-active { animation: bounce-in .5s; } .bounce-leave-active { animation: bounce-in .5s reverse; } </style> </head> <body> <div id="app"> <transition name="bounce"> <div v-if="show"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris facilisis enim libero, at lacinia diam fermentum id. Pellentesque habitant morbi tristique senectus et netus. </div> </transition> <button @click="handleClick">切换</button> </div> <script src="js/vue.js"></script> <script> // 1. 建立Vue的实例 let vm = new Vue({ el:'#app', data:{ show:false }, methods:{ handleClick:function(){ this.show = !this.show } } }); </script> </body> </html>
咱们这里还可使用自定义类:
既然咱们可使用自定义class,那么咱们就可使用开源的第三方CSS库,好比animate.css库。
https://daneden.github.io/animate.css/
使用很简单,直接替换上面咱们自定义的class就行。
使用animate.css注意事项:
一、必须使用自定义class的模式
enter-active-class=""
二、animated类放在前面,且是必须的
一、初次动画效果
上面例子中,咱们初次进入的时候没有动画效果,咱们能够作以下修改:
二、若是咱们但愿在上面的例子中还加入一开始咱们说的过渡效果,那该怎么作呢?
一、由于animate.css有一个本身的动画效果时长,fade也有一个opacity,那么以哪个为准呢?咱们可使用type="transition"来肯定哪一个为准。
二、咱们也能够本身设定动画效果时长样式:duration里面的enter为进入时长,leave为动画离开时长,都是针对过渡效果的。
Html
<div id="app"> <transition name="fade" @before-enter="beforeEnter" @enter="enter" > <div v-if="show"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris facilisis enim libero, at lacinia diam fermentum id. Pellentesque habitant morbi tristique senectus et netus. </div> </transition> <button @click="handleClick">切换</button> </div>
Js
methods:{ handleClick:function(){ this.show = !this.show }, beforeEnter: function (el) { el.style.opacity = 0 el.style.transformOrigin = 'left' }, enter: function (el, done) { Velocity(el, { opacity: 1, fontSize: '1.4em' }, { duration: 300 }) Velocity(el, { fontSize: '1em' }, { complete: done }) }, }
一、多个元素的过渡动画实现
Html
<div id="app"> <transition name="fade" mode="in-out"> <div v-if="show" key='one'>组件1</div> <div v-else key='two'>组件2</div> </transition> <button @click="handleClick">切换</button> </div>
style
<style> .fade-enter-active, .fade-leave-active { transition: opacity 1s; } .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ { opacity: 0; } </style>
注意:这里须要绑定一个key,由于vue会复用,因此不加key就不会有效果。
二、多个组件的过渡动画实现
Html
<div id="app"> <transition name="fade" > <child-one v-if="show"></child-one> <child-two v-else></child-two> </transition> <button @click="handleClick">切换</button> </div>
js
<script> Vue.component('child-one',{ template:'<div>child-one</div>' }) Vue.component('child-two',{ template:'<div>child-two</div>' }) // 1. 建立Vue的实例 let vm = new Vue({ el:'#app', data:{ show:false }, methods:{ handleClick:function(){ this.show = !this.show } } }); </script>
css
<style> .fade-enter-active, .fade-leave-active { transition: opacity .4s; } .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ { opacity: 0; } </style>
咱们能够经过Vue自带的compoent标签实现动态组件,data中show改为type,type:‘child-one’
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> .fade-enter-active, .fade-leave-active { transition: opacity .4s; } .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ { opacity: 0; } </style> </head> <body> <div id="app"> <transition name="fade" > <component :is="type"></component> </transition> <button @click="handleClick">切换</button> </div> <script src="js/vue.js"></script> <script> Vue.component('child-one',{ template:'<div>child-one</div>' }) Vue.component('child-two',{ template:'<div>child-two</div>' }) // 1. 建立Vue的实例 let vm = new Vue({ el:'#app', data:{ type:'child-one' }, methods:{ handleClick:function(){ this.type = this.type==='child-one'?'child-two':'child-one' } } }); </script> </body> </html>
当咱们但愿对列表进行过渡效果时,使用transition-group标签就能够了。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> .fade-enter-active, .fade-leave-active { transition: opacity 1s; color: red; } .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ { opacity: 0; } </style> </head> <body> <div id="app"> <transition-group name="fade"> <div v-for="item in list" key="item.id">{{item.title}}</div> </transition-group> <button @click="handleClick">增长</button> </div> <script src="js/vue.js"></script> <script> var count = 0 // 1. 建立Vue的实例 let vm = new Vue({ el:'#app', data:{ list:[] }, methods:{ handleClick:function(){ this.list.push({ id:count++, title:'hello kitty!' }) } } }); </script> </body> </html>
咱们能够将动画以组件的方式进行封装起来,之后须要使用这个动画时,直接经过插槽将组件放入插槽便可。
例子:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <script src='js/velocity.min.js'></script> </head> <body> <div id="app"> <fade :show="show"> <div> hello div </div> </fade> <fade :show="show"> <h1>hello H1</h1> </fade> <button @click="handleClick">增长</button> </div> <script src="js/vue.js"></script> <script> Vue.component('fade',{ props:['show'], template:`<transition @before-enter="handleBeforeEnter" @enter="handleEnter"> <slot v-if="show"></slot> </transition>`, methods:{ handleBeforeEnter:function(el){ el.style.color="red" }, handleEnter:function(el,done){ setTimeout(()=>{ Velocity(el, { opacity: 1, fontSize: '1.4em' }, { duration: 300 }) Velocity(el, { fontSize: '1em' }, { complete: done }) done() },2000) } } }) // 1. 建立Vue的实例 let vm = new Vue({ el:'#app', data:{ show:false }, methods:{ handleClick:function(){ this.show=!this.show } } }); </script> </body> </html>
咱们这里封装了一个fade组件,经过transition封装一个slot,里面能够支持N个内容。而后将动画效果封装到钩子函数,而后在钩子函数里面放入CSS效果。这样,就将动画效果彻底封装在一个组件中了,随时随地可使用这个带动画的组件啦。
写了这么多,其实就是开头的四种方式: