您好,登錄后才能下訂單哦!
本文將介紹Vue中的列表過渡,動態過渡, 以及可復用過渡是實現。
列表過渡
目前為止,關于過渡我們已經講到:
那么怎么同時渲染整個列表,比如使用 v-for
?在這種場景中,使用 <transition-group>
組件。在我們深入例子之前,先了解關于這個組件的幾個特點:
總是需要
提供唯一的 key
屬性值.列表的進入和離開過渡現在讓我們由一個簡單的例子深入,進入和離開的過渡使用之前一樣的 CSS 類名。
<div id="app1"> <button @click="add">Add</button> <button @click="remove">Remove</button> <transition-group name="list" tag="p"> <span v-for="item in items" :key="item" class="list-item"> {{item}} </span> </transition-group> </div>
.list-item{ display: inline-block; margin-right: 10px; } .list-enter-active, .list-leave-active{ transition: all 1s; } .list-enter, .list-leave-to{ opacity: 0; transform: translateY(30px); }
var app1 = new Vue({ el:'#app1', data:{ items:[1,2,3,4,5,6,7,8,9], nextNum:10 }, methods:{ randomIndex:function () { return Math.floor(Math.random() * this.items.length) }, add:function () { this.items.splice(this.randomIndex(), 0, this.nextNum++) }, remove:function () { this.items.splice(this.randomIndex(), 1) } } })
運行結果:
這個例子有個問題,當添加和移除元素的時候,周圍的元素會瞬間移動到他們的新布局的位置,而不是平滑的過渡,我們下面會解決這個問題。
列表的位移過渡
<transition-group>
組件還有一個特殊之處。不僅可以進入和離開動畫,還可以改變定位。要使用這個新功能只需了解新增的v-move
特性,它會在元素的改變定位的過程中應用。像之前的類名一樣,可以通過 name
屬性來自定義前綴,也可以通過 move-class
屬性手動設置。
v-move
對于設置過渡的切換時機和過渡曲線非常有用,你會看到如下的例子:
<div id="app2"> <button @click="shuffle">Shuffle</button> <transition-group name="flip-list" tag="ul"> <li v-for="item in items" :key="item"> {{item}} </li> </transition-group> </div>
.flip-list-move { transition: transform 1s; }
var app2 = new Vue({ el:'#app2', data:{ items:[1,2,3,4,5,6,7,8,9] }, methods:{ shuffle:function () { this.items = _.shuffle(this.items) } } })
這個例子需要添加以下引用
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>
運行結果:
這個看起來很神奇,內部的實現,Vue 使用了一個叫 FLIP 簡單的動畫隊列
使用 transforms 將元素從之前的位置平滑過渡新的位置。
我們將之前實現的例子和這個技術結合,使我們列表的一切變動都會有動畫過渡。
<div id="app3" class="demo"> <button @click="shuffle">Shuffle</button> <button @click="add">Add</button> <button @click="remove">Remove</button> <transition-group name="list-complete" tag="p"> <span v-for="item in items" :key="item" class="list-complete-item"> {{item}} </span> </transition-group> </div>
.list-complete-item{ transition: all 1s; display: inline-block; margin-right: 10px; } .list-complete-enter, .list-complete-leave-to{ opacity: 0; transform: translateY(30px); } .list-complete-leave-active{ position: absolute; }
var app3 = new Vue({ el:'#app3', data:{ items:[1,2,3,4,5,6,7,8,9], nextNum:10 }, methods:{ shuffle:function () { this.items = _.shuffle(this.items) }, randomIndex:function () { return Math.floor(Math.random() * this.items.length) }, add:function () { this.items.splice(this.randomIndex(), 0, this.nextNum++) }, remove:function () { this.items.splice(this.randomIndex(), 1) } } })
運行結果:
列表的漸進過渡
通過 data 屬性與 JavaScript 通信 ,就可以實現列表的漸進過渡:
<div id="app4"> <input v-model="query"> <transition-group name="staggered-fade" tag="ul" :css="false" @before-enter="beforeEnter" @enter="enter" @leave="leave"> <li v-for="(item, index) in computedList" :key="item.msg" :data-index="index"> {{item.msg}} </li> </transition-group> </div>
var app4 = new Vue({ el:'#app4', data:{ query:'', list:[ {msg:'Bruce Lee'}, {msg:'Jackie Chan'}, {msg:'Chuck Norris'}, {msg:'Jet Li'}, {msg:'Kung Furry'}, {msg:'Chain Zhang'}, {msg:'Iris Zhao'}, ] }, computed:{ computedList:function () { var vm = this return this.list.filter(function (item) { return item.msg.toLowerCase().indexOf(vm.query.toLowerCase()) !== -1 }) } }, methods:{ beforeEnter:function (el) { el.style.opacity = 0 el.style.height = 0 }, enter:function (el, done) { var delay = el.dataset.index * 150 setTimeout(function () { Velocity(el, {opacity:1, height:'1.6em'},{complete:done}) }, delay) }, leave:function (el, done) { var delay = el.dataset.index * 150 setTimeout(function () { Velocity(el, {opacity:0, height:0}, {complete:done}) }, delay) } } })
上述js代碼需要添加對Velocity引用:
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
運行結果如下:
可復用的過渡
過渡可以通過 Vue 的組件系統實現復用。要創建一個可復用過渡組件,你需要做的就是將<transition>或者 <transition-group>作為根組件,然后將任何子組件放置在其中就可以了。
下面的例子是將上一個列表漸進過渡的例子改為可復用的過渡的源碼:
<div id="app5"> <input v-model="query"> <my-transition :query="query" :list="list"> <li v-for="(item, index) in computedList" :key="item.msg" :data-index="index"> {{item.msg}} </li> </my-transition> </div>
Vue.component('my-transition', { template:` <transition-group name="staggered-fade" tag="ul" :css="false" @before-enter="beforeEnter" @enter="enter" @leave="leave"> <slot></slot> </transition-group>`, props:['query', 'list'], methods:{ beforeEnter:function (el) { el.style.opacity = 0 el.style.height = 0 }, enter:function (el, done) { var delay = el.dataset.index * 150 setTimeout(function () { Velocity(el, {opacity:1, height:'1.6em'},{complete:done}) }, delay) }, leave:function (el, done) { var delay = el.dataset.index * 150 setTimeout(function () { Velocity(el, {opacity:0, height:0}, {complete:done}) }, delay) } } }) var app5 = new Vue({ el:'#app5', data:{ query:'', list:[ {msg:'Bruce Lee'}, {msg:'Jackie Chan'}, {msg:'Chuck Norris'}, {msg:'Jet Li'}, {msg:'Kung Furry'}, {msg:'Chain Zhang'}, {msg:'Iris Zhao'}, ] }, computed:{ computedList:function () { var vm = this return this.list.filter(function (item) { return item.msg.toLowerCase().indexOf(vm.query.toLowerCase()) !== -1 }) } }, })
效果與上一個例子一致:
但是函數組件更適合完成這個任務。由于暫時還沒有學到render函數,所以暫時先不實現render函數組件。后面學到的時候再做打算。
動態過渡
在 Vue 中即使是過渡也是數據驅動的!動態過渡最基本的例子是通過 name 特性來綁定動態值。
<transition v-bind:name="transitionName"> <!-- ... --> </transition>
當你想用 Vue 的過渡系統來定義的 CSS 過渡/動畫 在不同過渡間切換會非常有用。
所有的過渡特性都是動態綁定。它不僅是簡單的特性,通過事件的鉤子函數方法,可以在獲取到相應上下文數據。這意味著,可以根據組件的狀態通過 JavaScript 過渡設置不同的過渡效果。
<div id="app6"> Fade In: <input type="range" v-model="fadeInDuration" min="0" :max="maxFadeDuration"> Fade Out: <input type="range" v-model="fadeOutDuration" min="0" :max="maxFadeDuration"> <transition v-bind:css="false" @before-enter="beforeEnter" @enter="enter" @leave="leave"> <p v-if="show">hello chain</p> </transition> <button @click="stop = true">Stop it</button> </div>
var app6 = new Vue({ el: '#app6', data: { show: true, fadeInDuration: 1000, fadeOutDuration: 1000, maxFadeDuration: 1500, stop: false }, mounted: function () { this.show = false }, methods: { beforeEnter: function (el) { el.style.opacity = 0 }, enter: function (el, done) { var vm = this Velocity(el, { opacity: 1 }, { duration: this.fadeInDuration, complete: function () { done() if (!vm.stop) vm.show = false } } ) }, leave: function (el, done) { var vm = this Velocity(el, { opacity: 0 }, { duration: this.fadeOutDuration, complete: function () { done() vm.show = true } } ) } } })
運行結果:
其中例子里的mounted是在Vue掛載完成,也就是模板中的html渲染到html頁面中時的一個鉤子函數,只會執行一次。具體內容可以理解下Vue的生命周期,這里就不贅述了。
但是如果這里不使用mounted的話,也是可以用初始渲染來實現,只不過比較麻煩。實現的方法是:
在transition中加入appear鉤子函數:@appear="appear",然后在vue實例的methods中添加appear方法:
appear: function (el, done) { var vm = this Velocity(el, { opacity: 1 }, { duration: this.fadeInDuration, complete: function () { done() if (!vm.stop) vm.show = false } } ) }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。