Vue列表过渡
前面的話
本文將詳細介紹Vue列表過渡
?
概述
前面分別介紹了單元素CSS過渡和JS過渡,以及多元素過渡。如何同時渲染整個列表呢?在這種情景中,需要使用<transition-group>組件
【<transition-group>】
<transition-group>不同于?<transition>, 它會以一個真實元素呈現:默認為一個?<span>。也可以通過?tag?特性更換為其他元素。而且其內部元素總是需要提供唯一的?key?屬性值
<transition-group name="list" tag="p"><!-- ... --></transition-group>?
普通過渡
下面是一個添加和刪除列表項的例子
<style> .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);} </style> <div id="list-demo" class="demo"><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> <script> new Vue({el: '#list-demo',data: {items: [1,2,3,4,5,6,7,8,9],nextNum: 10},methods: {randomIndex() {return Math.floor(Math.random() * this.items.length)},add() {this.items.splice(this.randomIndex(), 0, this.nextNum++)},remove() {this.items.splice(this.randomIndex(), 1)},} }) </script>?
平滑過渡
上面這個例子有個問題,當添加和移除元素的時候,周圍的元素會瞬間移動到他們的新布局的位置,而不是平滑的過渡
【v-move】
<transition-group>?組件還有一個特殊之處。不僅可以進入和離開動畫,還可以改變定位。要使用這個新功能只需了解新增的?v-move?特性,它會在元素的改變定位的過程中應用。像之前的類名一樣,可以通過?name?屬性來自定義前綴,也可以通過?move-class?屬性手動設置
在上面代碼中基礎上,做出如下改進:
1、增加.list-move的樣式,使元素在進入時實現過渡效果
2、在.list-leave-active中設置絕對定位,使元素在離開時實現過渡效果
<style> .list-item {display: inline-block;margin-right: 10px;} .list-move,.list-enter-active, .list-leave-active {transition: 1s;} .list-leave-active{position:absolute;} .list-enter, .list-leave-to{opacity: 0;transform: translateY(30px);} </style>?
變換過渡
下面接著利用move屬性,進行變換過渡,即一個列表中的列表項既不增加也不減少,只是不斷地變換其位置
<style> .list-move{transition: transform 1s;} </style> <div id="list-demo" class="demo"><button @click="shuffle">shuffle</button><transition-group name="list" tag="ul"><li v-for="item in items" :key="item">{{item}}</li></transition-group> </div> <script> new Vue({el: '#list-demo',data: {items: [1,2,3,4,5,6,7,8,9],},methods: {shuffle(){this.items = this.items.sort(()=>{return Math.random() - 0.5;})},} }) </script>下面的效果看起來很神奇,內部的實現,Vue 使用了一個叫?FLIP?簡單的動畫隊列,使用 transforms 將元素從之前的位置平滑過渡新的位置
下面將進入離開的例子和這個技術結合,?使列表的一切變動都會有動畫過渡
[注意]使用 FLIP 過渡的元素不能設置為?display: inline?。作為替代方案,可以設置為?display: inline-block?或者放置于 flex 中
<style> .list-item {display: inline-block;margin-right: 10px;} .list-move,.list-enter-active, .list-leave-active {transition: 1s;} .list-leave-active{position:absolute;} .list-enter, .list-leave-to{opacity: 0;transform: translateY(30px);} </style>以上代碼中,由于move、enter和leave都需要設置transition。因此,直接在元素上設置transition即可
<style> .list-item {display: inline-block;margin-right: 10px;transition: 1s;} .list-leave-active{position:absolute;} .list-enter, .list-leave-to{opacity: 0;transform: translateY(30px);} </style>下面是完整代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> .list-item {display: inline-block;margin-right: 10px;transition: 1s;} .list-leave-active{position:absolute;} .list-enter, .list-leave-to{opacity: 0;transform: translateY(30px);} </style> </head> <body> <div id="list-demo" class="demo"><button @click="shuffle">shuffle</button><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> <script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/vue.js"></script> <script> new Vue({el: '#list-demo',data: {items: [1,2,3,4,5,6,7,8,9],nextNum: 10},methods: {randomIndex() {return Math.floor(Math.random() * this.items.length)},add() {this.items.splice(this.randomIndex(), 0, this.nextNum++)},remove() {this.items.splice(this.randomIndex(), 1)}, shuffle(){this.items = this.items.sort(()=>{return Math.random() - 0.5;})},} }) </script> </body> </html>?
多維列表
FLIP 動畫不僅可以實現單列過渡,多維網格的過渡也同樣簡單
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> .container {width: 270px;margin-top: 10px;line-height:30px;text-align:center;} .cell {display: inline-block;width: 30px;height: 30px;outline: 1px solid #aaa;} .cell-move {transition:1s;} </style> </head> <body> <div id="list-demo" class="demo"><button @click="shuffle">shuffle</button><transition-group name="cell" tag="div" class="container"><span v-for="cell in cells" :key="cell.id" class="cell">{{ cell.number }}</span></transition-group> </div> <script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/vue.js"></script> <script> new Vue({el: '#list-demo',data: {cells: Array.apply(null, { length: 81 }).map(function (_, index) { return {id: index,number: index % 9 + 1}})},methods: {shuffle(){this.cells = this.cells.sort(()=>{return Math.random() - 0.5;})},} }) </script> </body> </html>?
漸進過渡
通過 data 屬性與 JavaScript 通信 ,就可以實現列表的漸進過渡
下面是使用CSS過渡實現的一個例子
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> .list-move,.list-enter-active, .list-leave-active {transition: 1s;} .list-leave-active{position:absolute;} .list-enter,.list-leave-to{opacity: 0;height:0;} </style> </head> <body> <div id="list-demo" class="demo"><input v-model="query"><transition-group name="list" tag="ul"><li v-for="(item, index) in computedList" :key="item" :data-index="index">{{item}}</li></transition-group> </div> <script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/vue.js"></script> <script> new Vue({el: '#list-demo',data: {query: '',list: ['HTML','CSS','Javascript','jQuery','Vue']},computed: {computedList() {return this.list.filter((item)=>{return item.toLowerCase().indexOf(this.query.toLowerCase()) !== -1})}}, }) </script> </body> </html>上面的效果中,列表項是一齊運動的。如果要實現依次運動的效果,則需要使用JS過渡來實現
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="list-demo" class="demo"><input v-model="query"><transition-group name="list" tag="ul" :css="false" @before-enter="beforeEnter" @enter="enter" @leave="leave"><li v-for="(item, index) in computedList" :key="item" :data-index="index">{{item}}</li></transition-group> </div> <script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/velocity.min.js"></script> <script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/vue.js"></script> <script> new Vue({el: '#list-demo',data: {query: '',list: ['HTML','CSS','Javascript','jQuery','Vue']},computed: {computedList() {return this.list.filter((item)=>{return item.toLowerCase().indexOf(this.query.toLowerCase()) !== -1})}}, methods: {beforeEnter(el) {el.style.opacity = el.style.height = 0},enter(el, done) {setTimeout(()=>{Velocity(el,{ opacity: 1, height: '1.6em' },{ complete: done })}, el.dataset.index * 150)},leave(el, done) {setTimeout(()=>{Velocity(el,{ opacity: 0, height: 0 },{ complete: done })}, el.dataset.index * 150)}}, }) </script> </body> </html>?
轉載于:https://www.cnblogs.com/xiaohuochai/p/7412798.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
- 上一篇: docker学习笔记(四)——Docke
- 下一篇: KVM调整cpu和内存