Vue實列之過渡和動畫,標籤過渡,多元件過渡,列表過渡

餘憨憨的學習日記發表於2020-11-02

過渡和動畫

過渡和動畫的概念

過渡:顧名思義,從一個狀態向另外一個狀態的過程,新的狀態替換了舊的狀態。不懂你就理解字面的意思,過渡就完事了。。。
動畫: 就是比過渡功能更多更強大一點,實在懶得解釋了,往後看吧~ ???

transition 元件

過渡型別說明
v-enter進入過渡的開始狀態,作用於開始的一幀
v-enter-active進入過渡生效時的狀態,作用整個過程
v-enter-to進入過渡的結束狀態,作用於結束的一幀
v-leave離開過渡的開始狀態,作用於開始的一幀
v-leave-active離開過渡生效時的狀態,作用於整個過程
v-leave-to離開過渡的結束狀態,作用於結束的一幀
<style>
    .chart{
        width: 200px;
        height: 50px;
        background-color: hotpink;
    }
    /* 進入和離開的整個過程*/
    .box-enter-active,.box-leave-active{
        transition: width 3s;
    }
    /*進入初始狀態和離開的結束狀態*/
    .box-enter,.box-leave-to{
        width: 0px;
    }
    /*進入的結束狀態和離開的開始狀態*/
    .box-enter-to,.box-leave{
        width: 200px;
    }
</style>
<body>
    <div id="app">
        <button  @click='toggle'>改變圖形寬度 yzx</button>
        <hr/> <!--水平線,為了好看一點,可以不寫-->
        <transition name="box">
            <!--設定新增過渡的div 標籤-->
            <div class="chart" v-if='show'></div>
        </transition>
    </div>  
<script>
    var vm = new Vue({
        el:'#app',
        data:{
            show:true
        },
        methods:{
            toggle(){
                this.show = ! this.show;
            }
        }
    })
</script>
</body>

在這裡插入圖片描述

自定義類名

Vue 中 transition 元件可以使用自定義的類名。
進入:enter-class,enter-active-class,enter-to-class
離開:leave-class,leave-active-class,leave-to-class
animate.css 是一個跨瀏覽器的 CSS 動畫庫,內建了很多經典 CSS3 動畫。
需要寫個link : “ < link href=“https://unpkg.com/animate.css@3.5.2/animate.min.css” rel=“stylesheet”/>”

<div id='app'>
    <button @click="show=!show">顯示和隱藏</button>

    <transition appear appear-active-class="animated swing"
    enter-active-class="animated bounceInLeft" leave-active-class="animated bunceOutLeft">
        <p v-if="show">過渡文字效果 yzx </p>
    </transition>
</div> 
<script>
    var vm = new Vue({
        el:'#app',
        data:{
            show:true
        }
    })
</script>

在這裡插入圖片描述

@keyframes 建立 CSS 動畫

@keyframes 規則建立動畫,就是將一套 CSS 樣式逐步演變成另一種樣式,在建立動畫的過程中可以多次改變 CSS 樣式,通過百分比或關鍵詞 from 和 to (等價於 0% 和 100%)來規定動畫的狀態。

    <style>
        div.circular{
            width: 100px;
            height: 100px;
            background-color:blueviolet;
            margin-top: 20px;
            border-radius: 50%;
            text-align: center;
            line-height: 100px;
            color: #fff;
        }
        .bounce-enter-active{
            animation: Anim 3s;
        }
        .bounce-leave-active{
            animation: Anim 3s reverse;
        }
        @keyframes Anim{
            0%{
                transform: scale(0);
                background:blueviolet;
            }
            100%{
                transform: scale(1);
                background: red;
            }
        }
    </style>  
</head>
<body>
    <div id="app">
        <button @click="show=!show">使用@keyframes 建立 CSS yzx</button>
        <transition  name="bounce" >
            <div class="circular" v-if="show">圓形啊</div>
        </transition>
    </div>
    <script>
        var vm = new Vue({
            el:'#app',
            data:{
                show:true
            }
        })
    </script>
</body>

有點抱歉,顯示效果背景有點小bug ,好像是瀏覽器渲染問題吧,評論區求個答案,我找半天沒搞好,抱歉???
在這裡插入圖片描述

多個元素過渡

不同標籤元素過渡

不同標籤元素可以使用 v-if 和 v- else 進行過渡

<div id="app">
    <transition>
    <ul v-if="items.length >0">
        <li>yzx 01</li>
        <li>yzx 02</li>
    </ul>
    <p v-else>抱歉,沒有找到哦~</p>
    </transition>
</div>  
<script>
    var vm = new Vue({
        el:'#app',
        data:{
            items:[]
        }
    })
</script>

在這裡插入圖片描述

相同標籤元素過渡

當有相同標籤的元素切換時,需要通過 key 特性設定唯一值來標記。

    <div id="app">
        <button @click="saving=!saving">切換編輯或儲存yzx</button>
        <transition >
            <button v-if="saving" key="save">儲存</button>
            <button v-else key="edit"> 編輯</button>
        </transition>
    </div>
    <script>
        var vm = new Vue({
            el:"#app",
            data:{
                saving: true
            }
        })
    </script>

在這裡插入圖片描述

過渡模式

過渡模式原理,設定有序的過渡而不是同數發生過渡,在transition 中加入 mode 屬性,該屬性有以下兩個值:
in-out:表示新元素先進性過渡,完成之後當前元素過渡離開
out-in:表示當前元素先進行過渡,完成之後新元素過渡進入

	<style>
		.fade-enter,.fade-leave-to{
			opacity: 0;
		}
		.fade-enter-active,.fade-leave-active{
			transition: opacity .5s;
		}
	</style>
-------------------------------------------------
<body>
<div id="app">
	<transition name="fade" mode="out-in">
	  <button  :key="isOff" @click="isOff=!isOff">{{isOff? 'Off': 'On'}}</button>
	</transition>
</div>	
<script>
	var vm = new Vue({
		el:'#app',
		data:{
			isOff:false
			}
	})
</script>
</body>

在這裡插入圖片描述

多個元件過渡

多個元件之間的過渡,只需要使用動態元件即可,動態元件需要通過 Vue 中, < component>元素繫結 is 元素來實現多元件的過渡。

	<style>
		.fade-enter,.fade-leave-to{
			opacity: 0;
		}
		.fade-enter-active,.fade-leave-active{
			transition: opacity .5s ease;
		}
	</style>
--------------------------------------------------------------------
<body>
<template id='example1'><span>我是登入元件</span></template>
<template id='example2'><span>我是註冊元件</span></template>
<div id="app">
<a href="javascript:;" @click="compontentName='example1'">登入 yzx</a>
<a href="javascript:;" @click="compontentName='example2'">註冊 yzx</a>
<transition name="fade" mode="in-out">
	<component :is="compontentName"></component> <!--繫結 is 屬性-->
</transition>
</div>	
<script>
	Vue.component('example1',{
	   template:'#example1'
	})
	Vue.component('example2',{
	   template:'#example2'
	})
	var vm = new Vue({
		el:'#app',
		data:{
			compontentName:''
		}
	})
</script> 

點註冊時,登入元件先進來再出去,in-out ,注意觀察效果理解。
在這裡插入圖片描述

列表過渡

寫一個列表的進入和離開過渡:

	<style>
		.list-item {
			display: inline-block;
			margin-right: 20px;
			background-color:hotpink;
			border-radius: 50%;
			width: 30px;
			height: 30px;
			text-align: center;
			line-height: 30px;
			color: #fff;
		}
		.list-enter-active,.list-leave-active{
			transition: all 1s;
		}
		.list-enter,.list-leave-to{
			opacity: 0;
			transform: translateY(30px);
		}
	</style>
------------------------------
<body>
<div id="app">
   <button @click="add">隨機插入一個數字</button>
   <button @click="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>
	var vm = new Vue({
		el:"#app",
		data:{
			items:[1,2,3,4,5],
			netNum:6
		},
		methods:{
			randomindex(){
				return Math.floor(Math.random()*this.items.length)
			},
			add(){
				this.items.splice(this.randomindex(),0,this.netNum++)
			},
			remove(){
                this.items.splice(this.randomindex(),1)
			}
		}		
	})
</script>

在這裡插入圖片描述
上述的程式碼有些許生硬,所以我們加一行程式碼,讓過渡變得自然一點:

.list-move{
			transition: transform 1s;
		}

在這裡插入圖片描述

列表的排序過渡

Vue使用了FLIP簡單動畫佇列來實現排序過渡,所以即使沒有插入或者移除元素,對於元素順序的變化也支援過渡動畫。FLIP動畫能提高動畫的流暢度,可以解決動畫的卡頓、閃爍等不流暢的現象,它不僅可以實現單列過渡,也可以實現多維網格的過渡。FLIP代表First、Last、lnvert、Play。
這是lodash.js 的連結:
< script src=“https://cdn.bootcss.com/lodash.js/4.17.4/lodash.min.js”>< /script>
實現一個 隨機排序的效果:

<body>
    <style>
		.list-item {
			display: inline-block;
			margin-right: 20px;
			background-color:hotpink;
			border-radius: 50%;
			width: 30px;
			height: 30px;
			text-align: center;
			line-height: 30px;
			color: #fff;
		}
		.list-move{
			transition: transform 1s;
		}
	</style>
------------------------------------------------------------
<body>
<div id="app">
   <button @click="shuffle"> 點選隨機排序 yzx</button>
   <transition-group name="list" tag="p">
	<span v-for="item in items" :key="item" class="list-item">{{item}}</span>
   </transition-group>
</div>
<script>
	var vm = new Vue({
		el:"#app",
		data:{
			items:[1,2,3,4,5]
		},
		methods:{
            shuffle(){
                //shuffle 會對陣列重新排序
                this.items = _.shuffle(this.items);
            }
        }
	})
</script>

在這裡插入圖片描述

列表的交錯過渡

在Vue中可以實現列表的交錯過渡效果,它是通過data屬性與JavaScript通訊來實現的。接下來我們通過案例來講解如何使用鉤子函式結合Velocity.js庫實現搜尋功能,根據關鍵字來篩選出符合要求的列表資料,並新增過渡效果。
< script src=“https://cdnjs.cloudflare.com/ajax/libs/velocity/1.5.0/velocity.min.js”></ script>
先說抱歉,有點小問題,就是你輸入仙女可以查到,你刪掉女,然後顯示就有點報錯了,應該跟我這個連結檔案有點關係吧,正常查沒有問題的。

<script>
    var vm =  new Vue({
        el:"#app",
        data(){
          return {
              query:'',
              items:[{
                  msg:'仙女'
              },{
                  msg:'仙氣飄飄'
              },{
                  msg:'可可愛愛'
              },{
                  msg:'沒有腦袋'
              },{
                  msg:'仙女本人'
              }
              ]
          }
        },
        computed:{
            resultList(){
            //根據使用者輸入的內容,查詢 items
            var query = this.query;
            var items = this.items;
            return items.filter(function(item){
                return item.msg.indexOf(query) !== -1;
            })
            }
        },
        returnList(){
            //根據使用者輸入的內容,查詢 items
            var query = this.query;
            var items = this.items;
            return items.filter(function(item){
                return item.msg.indexOf(query) !== -1;
            })
        
        },
        methods:{
            beforeEnter(el){
                el.style.opactity = 0
                el.style.height = 0
            },
            enter(el,done){
                //交錯過渡,每個 li 都有延遲
                var deplay = el.dataset.index *150;
                setTimeout(function(){
                    Velocity(el,{
                        opactity:1,
                        height:'1.6em'
                    },{
                        complete:done
                        });
                })
            },
            leave(el,done){
                var deplay = el.dataset.index *150;
                setTimeout(function(){
                    Velocity(el,{
                        opactity:0,
                        height:0
                    },{
                        complete:done
                        });
                })
            }
        }
    })
</script>

未經允許,禁止轉載 ~ 今天就先這樣吧,實在太困啦,後面沒寫的會補充的,仙女也是要睡覺覺的?‍♀️

相關文章