Vue.js學習筆記:過渡效果(含列表過渡)
Vue 提供了 transition
的封裝元件,在下列情形中,可以給任何元素和元件新增 entering/leaving 過渡
- 條件渲染 (使用
v-if
) - 條件展示 (使用
v-show
) - 動態元件
- 元件根節點
一、單元素過渡
- 一般需要過渡的元素要放在
<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
特性來繫結動態值。