1. 程式人生 > >Vue.js學習筆記:過渡效果(含列表過渡)

Vue.js學習筆記:過渡效果(含列表過渡)

Vue 提供了 transition 的封裝元件,在下列情形中,可以給任何元素和元件新增 entering/leaving 過渡

  • 條件渲染 (使用 v-if
  • 條件展示 (使用 v-show
  • 動態元件
  • 元件根節點

一、單元素過渡

  1. 一般需要過渡的元素要放在<transition> <transition>元件中 ,過渡有四個狀態 
    ①. enter 元素進入時第一幀的狀態 
    ②. enter-active 元素從進入第一幀後到完成過渡的這一過程的狀態 
    ③. leave 元素離開時的第一幀狀態 
    ④. leave-active 元素離開第一幀後到完成過渡的這一過程的狀態 
    列如: 
    2 . css過渡

html

<button v-on:click="show = !show">Toggle</button>
	<transition name="fade">
	  	<p v-if="show">hello,看我漸漸地消失。</p>
	</transition>

css
.fade-enter-active, .fade-leave-active {
  transition: opacity .5s
}
.fade-enter, .fade-leave-to {
  opacity: 0
}

js
new Vue({
	  el: '#demo',
	  data: {
	    show: true
	  }
	})


注意:

     對於這些在 enter/leave 過渡中切換的類名,v- 是這些類名的字首(也就是例子中的fade,這個是可以自定義的)。使用 <transition name="fade"> 可以重置字首,比如 v-enter 替換為 fade-enter。下面會介紹

二.自定義過渡類名

自定義過渡類就不需要 中的name屬性了。類名可以是自己隨意起,也可引入第三方動畫庫animate.css, 但是需要在 加入一些新增類名的屬性

  • enter-class=類名 
  • enter-active-class=類名 (常用) 
  • leave-class=類名 
  • leave-active-class=類名 (常用)

在引入第三方動畫庫 animate.css 時 以上屬性要先新增 animated 類, 在新增 動畫類名,例如: 
enter-class=”animated tada “


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <link rel="stylesheet" type="text/css" href="css/animate.min.css">
</head>
<body>
<div id="demo">
	<button @click="show = !show">看我</button>
	<transition 
	enter-active-class="lookshow"
	leave-active-class="animated tada"
	>
		<p v-if="show">hello</p>
	</transition>
</div>
<script type="text/javascript" src='js/vue.js'></script>
<script type="text/javascript">
	new Vue({
	  el: '#demo',
	  data: {
	    show: true
	  }
	})
</script>
</body>
</html>

注意:這裡要加上 animated 才會有效果 (第一個是我自己寫的類名,不用加,但是引入animate.css 需要在前面加animate)

同時使用 Transitions 和 Animations

Vue 為了知道過渡的完成,必須設定相應的事件監聽器。它可以是 transitionend 或animationend ,這取決於給元素應用的 CSS 規則。如果你使用其中任何一種,Vue 能自動識別型別並設定監聽。

但是,在一些場景中,你需要給同一個元素同時設定兩種過渡動效,比如 animation 很快的被觸發並完成了,而 transition 效果還沒結束。在這種情況中,你就需要使用type 特性並設定 animation 或 transition 來明確宣告你需要 Vue 監聽的型別。

三.JavaScript 鉤子

① before-enter 
② enter 
③ after-enter 
④ enter-cancelled (在 v-show 中應用) 
⑤ before-leave 
⑥ leave 
⑦ after-leave 
⑧ leave-cancelled (在 v-show 中應用)

       這些鉤子函式可以結合 CSS transitions/animations 使用,也可以單獨使用。

      當只用 JavaScript 過渡的時候, 在 enter 和 leave 中,回撥函式 done 是必須的 。 
否則,它們會被同步呼叫,過渡會立即完成。

如:


四.初始渲染的過渡

可以通過 appear 特性設定節點的在初始渲染的過渡
<transition appear>
  <!-- ... -->
</transition>
這裡預設和進入和離開過渡一樣,同樣也可以自定義 CSS 類名。

<transition
  appear
  appear-class="custom-appear-class"
  appear-to-class="custom-appear-to-class" (2.1.8+)
  appear-active-class="custom-appear-active-class"
>
  <!-- ... -->
</transition>

自定義 JavaScript 鉤子:

<transition
  appear
  v-on:before-appear="customBeforeAppearHook"
  v-on:appear="customAppearHook"
  v-on:after-appear="customAfterAppearHook"
  v-on:appear-cancelled="customAppearCancelledHook"
>
  <!-- ... -->
</transition>

五.多元素過渡

1.實現多個元素過渡用 
① v-if 和 v-else 或 v-else-if (兩個相鄰元素要求不一樣)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style type="text/css">
    	.fade-enter-active, .fade-leave-active {
		  transition: opacity .5s
		}
		.fade-enter, .fade-leave-to /* .fade-leave-active in below version 2.1.8 */ {
		  opacity: 0
		}
    </style>
</head>
<body>
<div id="demo">
	<button @click="show = !show">點選檢視變化</button>
	<transition name="fade">      
		<div v-if="show">
		    請看我的變化div
		</div>
		<p v-else="fade">我也會變化pppp</p>
	</transition>
</div>
<script type="text/javascript" src='js/vue.js'></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
<script type="text/javascript">
new Vue({
    el : "#demo",
    data : {
        show : true
    }
})
</script>
</body>
</html>

② 利用 屬性 key (推薦)
當有相同標籤名的元素切換時,需要通過key 特性設定唯一的值來標記以讓 Vue 區分它們否則 Vue 為了效率只會替換相同標籤內部的內容。即使在技術上沒有必要,給在 <transition> 元件中的多個元素設定 key 是一個更好的實踐。 ③ v-if 和 key屬性 混合使用
 <style type="text/css">
    	.fade-enter-active, .fade-leave-active {
		  transition: opacity .5s
		}
		.fade-enter, .fade-leave-to /* .fade-leave-active in below version 2.1.8 */ {
		  opacity: 0
		}
    </style>

<div id="demo">
 <!-- v-if 、v-show 和 key 配合切換更多元素-->
      <button @click="showa">點選檢視變化</button>
      <transition name="fade">      
        <div v-if="show == 'one'" key="one">
            oneoneoneone
        </div>
        <div v-if="show == 'two'" key="two">
           twotwotwotwo
        </div>
        <div v-if="show == 'three'" key="three">
           threethreethree
        </div>
      </transition>
</div>

<script type="text/javascript">
new Vue({
    el : "#demo",
    data : {
        show : true
    },
    methods:{
        showa:function (){
			if(this.show == 'one'){
				return this.show = 'two';
			}else if(this.show == 'two'){
				return this.show = 'three';
			}else{
				return this.show = 'one';
			}
        }
    }
    
})
</script>

2.過渡模式 
在多個元素過渡時,這些元素會同時出發,vue 提供了兩個屬性,在 中加入 mode 屬性,它有兩個值

A.in-out: 新元素先進行過渡,完成之後當前元素過渡離開。 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style type="text/css">

	.no-mode-translate-demo-wrapper {
	  position: relative;
	  height: 18px;
	}
	.no-mode-translate-demo-wrapper button {
	  position: absolute;
	}
	.no-mode-translate-fade-enter-active, .no-mode-translate-fade-leave-active {
	  transition: all 1s;
	}
	.no-mode-translate-fade-enter, .no-mode-translate-fade-leave-active {
	  opacity: 0;
	}
	.no-mode-translate-fade-enter {
	  transform: translateX(31px);
	}
	.no-mode-translate-fade-leave-active {
	  transform: translateX(-31px);
	}

    </style>
</head>
<body>
<div id="app">
    <div id="no-mode-demo" class="no-mode-translate-demo-wrapper ">
        <transition name="no-mode-translate-fade" mode="in-out">
            <button v-if="on" key="on" @click="on = false">on</button>
            <button v-else="" key="off" @click="on = true">off</button>
        </transition>
    </div>
</div>
<script type="text/javascript" src='js/vue.js'></script>
<script type="text/javascript">
	new Vue({
        el: '#no-mode-demo',
        data: {
            on: false
        }
    })
</script>
</script>
</body>
</html>


B.out-in: 當前元素先進行過渡,完成之後新元素過渡進入。

當把上面例子中<transition name="no-mode-translate-fade" mode="in-out">mode="in-out"

改為mode="out-in"時,效果是不一樣。

六.多元件過渡

多個元件的過渡簡單很多 - 我們不需要使用 key 特性。相反,我們只需要使用動態元件component
1.多元件過渡,利用 is 屬性
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style type="text/css">
.fade-enter-active,.fade-leave-active {
 transition: all 1s linear;
}
.fade-enter,.fade-leave-active {
  opacity: 0;
  transform:translateX(50px);
}
    </style>
</head>
<body>
<div id="app">
	<button @click="show">點選檢視變化</button>
	<transition name="fade" mode = "out-in">      
	    <component v-bind:is="view"></component>    
	    <!-- 元件替換用 is屬性 -->
	</transition>
</div>
<script type="text/javascript" src='js/vue.js'></script>
<script type="text/javascript">
new Vue({
	el: '#app',
	data:{
        view:"a-view",
    },
    components: {
		"a-view":{
			template:"<div>我是第一個模板</div>"
		},
		"b-view":{
			template:"<div>我是第二個模板</div>"
		}
    },
    methods:{
        show:function(){
            this.view = this.view == "a-view"?"b-view":"a-view";
        }
    }
})
</script>
</body>
</html>

七.列表過渡

列表的過渡需要用 v-for 和 <transition-group> </transition-group> 元件 
注意: 
① 列表 <transition-group> </transition-group> 在頁面渲染出來是個 span 標籤, 如果你想更改它用 tag 屬性。例如 <transition-group tag="div"> </transition-group>渲染出來就是div 

② 列表在迴圈時 要給每一個列表項新增唯一的key 屬性值。這樣列表才會有過渡效果

1. FLIP 簡單的動畫佇列(使用 transforms 將元素從之前的位置平滑過渡新的位置)

列表的位移過渡(<transition-group> 元件還有一個特殊之處。不僅可以進入和離開動畫,還可以改變定位。

只需瞭解新增的 v-move 特性:v-move 對於設定過渡的切換時機和過渡曲線非常有用。

如:

需要注意的是使用 FLIP 過渡的元素不能設定為 display: inline 。作為替代方案,可以設定為 display: inline-block 或者放置於 flex 中

引入lodash.min.js 實現隨機排序

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <link rel="stylesheet" type="text/css" href="css/animate.min.css">
    <style type="text/css">
		span{
		    display:inline-block;
		    padding:10px;
		}
		.position{position: absolute;} 
		.list-complete-item{transition:all .3s linear;}
    </style>
</head>
<body>
<div id="myDiv">
	<button @click="add">隨機增加數字</button>
	<button @click="remvoed">隨機刪除數字</button>
	<button @click="suffle">隨機排序</button>
	<transition-group tag="div" 
	 name="flip-list"
	 enter-active-class="animated bounceInUp position"
	 leave-active-class="animated bounceOutDown position">     
	 	<span v-for="item in list" :key="item" class="list-complete-item">{{item}}</span>
	</transition-group>
</div>
<script type="text/javascript" src='js/vue.js'></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>
<script type="text/javascript">
new Vue({
	el:"#myDiv",
    data:{ //這裡寫程式碼片
        list:[1,2,3,4,5],
        addNumber:5
    },
    methods:{
        randomIndex:function(){ //隨機插入的位置
            return Math.floor(Math.random()*this.list.length);
        },
        add:function(){
            this.list.splice(this.randomIndex(),0,++this.addNumber)
        },
        remvoed:function(){
            this.list.splice(this.randomIndex(),1);
        },
        suffle:function(){
            this.list = _.shuffle(this.list)
        }
    }
})
</script>
</body>
</html>


注意:FLIP 動畫不僅可以實現單列過渡,多維網格的過渡也同樣簡單:

2.列表的漸進過渡

通過 data 屬性與 JavaScript 通訊 ,就可以實現列表的漸進過渡

3.可複用的過渡

要建立一個可複用過渡元件,你需要做的就是將 <transition> 或者 <transition-group> 作為根元件,然後將任何子元件放置在其中就可以了。

4.動態過渡

動態過渡最基本的例子是通過 name 特性來繫結動態值。

<transition v-bind:name="transitionName"> <!-- ... --></transition>