SPA 中組件的切換有一種生硬的隱藏顯示感受,爲了更好的用戶體驗,讓組件切換時淡出淡入,Vue 提供了專門的組件 transition。javascript
每一個狀態在使用的時候都是在 CSS 中使用,結合組件 transition 的 name 屬性。如 <transition name="fade"></transition>
,對應的是 fade-
加上每一個狀態:fade-enter
。css
使用到組件 transition
的屬性: name
。html
<style type="text/css" media="screen"> /*初始狀態*/ .fade-enter{opacity: 0;} /*已經準備就緒*/ .fade-enter-active{transition: all .5s;} /*已經消失*/ .fade-leave-active{opacity: 0; transition: all .5s;} </style> <div id="app"> <input type="button" :value="show ? 'hide' : 'show'" @click="show = !show" /> <br/> <transition name="fade"> <img src="imgs/green.jpg" v-show="show" /> </transition> </div> <script type="text/javascript"> var vm = new Vue({ el: '#app', data: { show: true } }) </script>
效果預覽vue
使用到組件 transition
的屬性: name
。java
<style type="text/css" media="screen"> .fade-enter-active{animation: fade-in .5s;} .fade-leave-active{animation: fade-out .5s;} @keyframes fade-in{ from{ opacity: 0; } to{ opacity: 1; } } @keyframes fade-out{ from{opacity: 1;} to{opacity: 0;} } </style> <div id="app"> <input type="button" :value="show ? 'hide' : 'show'" @click="show = !show" /> <br/> <transition name="fade"> <img src="imgs/green.jpg" v-if="show" /> </transition> </div> <script type="text/javascript"> var vm = new Vue({ el: '#app', data: { show: true } }) </script>
效果預覽git
第一次加載時的過渡效果,使用到組件 transition
的屬性: appear
appear-class
appear-active-class
。github
<style type="text/css" media="screen"> .fade-enter{opacity: 0;} .fade-enter-active{transition: all 3s;} </style> <div id="app"> <transition appear appear-class="fade-enter" appear-active-class="fade-enter-active"> <img src="imgs/green.jpg" /> </transition> </div> <script type="text/javascript"> var vm = new Vue({ el: '#app' }) </script>
效果預覽app
同時生效的進入和離開的過渡不能知足全部要求,因此 Vue 提供了 過渡模式:dom
使用到組件 transition
的屬性: mode
。ide
<style type="text/css" media="screen"> .fade-enter{opacity: 0;} .fade-enter-active{transition: all .5s;} .fade-leave-active{opacity: 0; transition: all .5s;} </style> <div id="app"> <fieldset> <legend><h3>mode = in-out</h3></legend> <div> <input type="button" :value="red ? 'green' : 'red'" @click="red = !red" /> <br/> <transition name="fade" mode="in-out"> <img src="imgs/red.jpg" v-if="red" key="red"/> <img src="imgs/green.jpg" v-else key="green"/> </transition> </div> </fieldset> <fieldset> <legend><h3>mode = out-in</h3></legend> <div> <input type="button" :value="flag == 1 ? 'green' : flag == 2 ? 'yellw' : 'red'" @click="flag = flag == 1 ? 2 : flag == 2 ? 3 : 1" /> <br/> <transition name="fade" mode="out-in"> <img src="imgs/red.jpg" v-if="flag == 1" key="red"/> <img src="imgs/green.jpg" v-else-if="flag == 2" key="green"/> <img src="imgs/yellow.jpg" v-else key="yellow" /> </transition> </div> </fieldset> </div> <script type="text/javascript"> var vm = new Vue({ el: '#app', data: { red: true, flag: 1 } }) </script>
v-for 生成列表過渡效果要使用組件 transition-group
,組件提供屬性 tag
表示該組件將會渲染成對應的 DOM 節點,其它的使用和 transition
同樣。
<style type="text/css" media="screen"> *{list-style: none;} li{width: 300px; margin-bottom: 5px; padding: 10px 20px; background-color: #ccc;} .list-enter{opacity: 0; transform: translateX(300px);} .list-enter-active{transition: all .5s;} .list-leave-active{transition: all .5s; opacity: 0; transform: translateX(-300px);} </style> <div id="app"> <p> <input type="button" value="AddItem" @click="addItem"> <input type="button" value="RemoveItem" @click="removeItem"> </p> <transition-group tag="ul" name="list"> <li v-for="(item, index) in items" :key="item">Item {{index}}</li> </transition-group> </div> <script type="text/javascript"> var vm = new Vue({ el: '#app', data: { items: [1,2,3] }, methods: { randomIndex: function(){ return parseInt(this.items.length * Math.random()); }, addItem: function(){ this.items.splice(this.randomIndex(), 0, this.items.length + 1); }, removeItem: function(){ this.items.splice(this.randomIndex(), 1); } } }) </script>
咱們能夠經過如下特性來自定義過渡類名:
他們的優先級高於普通的類名,這對於 Vue 的過渡系統和其餘第三方 CSS 動畫庫,如 Animate.css 結合使用十分有用。
<link rel="stylesheet" type="text/css" href="animate.css"> <div id="app"> <button @click="show = !show">Toggle render</button> <transition enter-active-class="animated jello" leave-active-class="animated bounceOutRight"> <div v-if="show"><img src="./imgs/green.jpg" /></div> </transition> </div> <script type="text/javascript"> var vm = new Vue({ el: '#app', data: { show: true } }) </script>
除了用CSS過渡的動畫來實現vue的組件過渡,還能夠用JavaScript的鉤子函數來實現,在鉤子函數中直接操做DOM。咱們能夠在屬性中聲明如下鉤子:
<transition v-on:before-enter="beforeEnter" v-on:enter="enter" v-on:after-enter="afterEnter" v-on:enter-cancelled="enterCancelled" v-on:before-leave="beforeLeave" v-on:leave="leave" v-on:after-leave="afterLeave" v-on:leave-cancelled="leaveCancelled" > </transition> <script type="text/javascript"> var vm = new Vue({ el: '#app', methods: { // 過渡進入 // 設置過渡進入以前的組件狀態 beforeEnter: function (el) { // ... }, // 設置過渡進入完成時的組件狀態 enter: function (el, done) { // ... done() }, // 設置過渡進入完成以後的組件狀態 afterEnter: function (el) { // ... }, enterCancelled: function (el) { // ... }, // 過渡離開 // 設置過渡離開以前的組件狀態 beforeLeave: function (el) { // ... }, // 設置過渡離開完成時地組件狀態 leave: function (el, done) { // ... done() }, // 設置過渡離開完成以後的組件狀態 afterLeave: function (el) { // ... }, // leaveCancelled 只用於 v-show 中 leaveCancelled: function (el) { // ... } } }) </script>