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效果。這樣,就將動畫效果徹底封裝在一個組件中了,隨時隨地可使用這個帶動畫的組件啦。
寫了這麼多,其實就是開頭的四種方式: