這里是官方文檔:http://cn.vuejs.org/v2/guide/transitions.html
一、開始
結構如上一篇文章,我們在movie.vue中來寫我們的第一個小過渡效果:
在movie.vue寫入:
<template>
<div id="movie">
<button @click="showMenu" class="btn">{{text}}</button>
<transition name="move">
<div class="menu" v-show="show">
<div class="inner inner-1">1</div>
</div>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
show: false
};
},
methods: {
showMenu() {
this.show = !this.show;
}
},
computed: {
text() {
return this.show ? '收' : '開';
}
}
};
</script>
<style>
#movie{
margin-top:10px;
}
.btn{
position: fixed;
top:60px;
left:50%;
z-index:10;
width:50px;
height:50px;
line-height:50px;
border-radius: 50%;
border:none;
outline:none;
color:#fff;
font-size:18px;
background:orange;
}
.inner-1{
display: inline-block;
position:absolute;
width:30px;
height:30px;
line-height:30px;
border-radius:50%;
background: red;
text-align:center;
color:#fff;
transition:all 0.4s;
left:-50px;
top:20px;
}
.menu{
position:fixed;
top:60px;
left:50%;
width:50px;
height:50px;
border-radius:50%;
transition:all 0.7s linear;
}
/*上面主要都是樣式代碼*/
.move-enter-active > .inner-1{
transform: translate3d(0,0,0);
}
.move-enter > .inner-1,
.move-leave-active >.inner-1{
transition-timing-function: ease-in-out ;
transform:translate3d(60px,0,0) ;
}
</style>
再點開movie.vue,可以看到一個最簡單的過渡效果:

這里,我把enter為動畫的起始狀態,leave-active理解為返回最終狀態(這個過渡效果類似CSS3的animation)
其實也可以直接用CSS3的animation,只需要做如下修改
<template>
<div id="movie">
<div id="example-2">
<button @click="showMenu" class="btn">{{text}}</button>
<transition name="bounce">
<p style="padding-left:50px" v-if="show">Look at me!</p>
</transition>
</div>
</div>
</template>
<script>
export default {
data() {
return {
show: false
};
},
methods: {
showMenu() {
this.show = !this.show;
}
},
computed: {
text() {
return this.show ? '逝' : '現';
}
}
};
</script>
<style>
#movie{
margin-top:10px;
}
.btn{
position: fixed;
top:60px;
left:50%;
z-index:10;
width:50px;
height:50px;
line-height:50px;
border-radius: 50%;
border:none;
outline:none;
color:#fff;
font-size:18px;
background:orange;
}
.bounce-enter-active {
animation: bounce-in 2s;
}
.bounce-leave-active {
animation: bounce-out 2s;
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
@keyframes bounce-out {
0% {
transform: scale(1);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(0);
}
}
</style>
運行

其實就vue幫你加了個class又幫你移除了
二、多個組件過渡
組件的過渡可以痛通過綁定選中值實現
這里我們再修改下movie.vue
<template>
<div id="movie">
<div class="radio">
<input type="radio" id="one" value="v-a" v-model="view">
<label for="one">A</label>
<input type="radio" id="two" value="v-b" v-model="view">
<label for="two">B</label>
</div>
<div class="show">
<transition name="component-fade" mode="out-in">
<component :is="view"></component>
</transition>
</div>
</div>
</template>
<script>
export default {
data() {
return {
view: 'v-a',
picked: 'one'
};
},
components: {
'v-a': {
template: '<div>Component A</div>'
},
'v-b': {
template: '<div>Component B</div>'
}
}
};
</script>
<style>
#movie{
margin-top:25px;
width:100%;
height:200px;
display:flex;
flex-direction: column;
align-items: center;
}
.component-fade-enter-active .conpoment-fade-leave-active{
opacity: 1;
transition: all 0.5s ease;
}
.component-fade-enter, .component-fade-leave-active {
opacity: 0;
}
</style>
這樣我們就可以在選擇的數據變化時實現簡單的過渡:

三、JavaScript 鈎子
script鈎子其實就是一一設定綁定狀態的變化,設置相對應的過渡效果,看下例子:
html代碼:
<div id="movie"> <img class="target" src="./basket.png"></img> <transition v-for="ball in balls" name="shooting" @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter"> <!--外層做縱向動畫--> <div class="ball" v-show="ball.show"> <!--內層做橫向動畫--> <div class="inner"></div> </div> </transition> <img class="shoot" @click="shoot($event)" src="./player.png"></img> </div>
script代碼:
data() { return { balls: [ { show: false }, { show: false }, { show: false }, { show: false }, { show: false } ], dropBalls: [] }; }, methods: { shoot(el) { var balls = this.balls; for (let i in balls) { let ball = balls[i]; if (!ball.show) { ball.show = true; ball.el = el.target; this.dropBalls.push(ball); return; } } }, beforeEnter:function(el) { let count = this.balls.length; while (count--) { let ball = this.balls[count]; if (ball.show) { let rect = ball.el.getBoundingClientRect(); let left = rect.left ; console.log(el); let top = -(window.innerHeight - rect.top - 520); el.style.display = ''; el.style.webkitTransform = `translate3d(0,${top}px,0)`; el.style.transform = `translate3d(0,${top}px,0)`; let inner = el.getElementsByClassName('inner')[0]; inner.style.webkitTransform = `translate3d(${left}px,0,0)`; inner.style.transform = `translate3d(${left}px,0,0)`; } } }, enter:function(el) { /* eslint-disable no-unused-vars */ let refresh = el.offsetHeight; this.$nextTick(() => { el.style.webkitTransform = 'translate3d(0,0,0)'; el.style.transform = 'translate3d(0,0,0)'; let inner = el.getElementsByClassName('inner')[0]; inner.style.webkitTransform = 'translate3d(0,0,0)'; inner.style.transform = 'translate3d(0,0,0)'; }); }, afterEnter:function(el) { let ball = this.dropBalls.shift(); if (ball) { ball.show = false; el.style.display = 'none'; } } }
其實就是設置相應的變化位置,完成變化,最后看下效果:

四、表單過渡(transition-group)
其實這個transition-group相當於給每一個元素添加一個transition,但需要指定唯一的標識key,看下代碼:
<template>
<div id="movie">
<div id="list-demo" class="demo">
<button v-on:click="add">Add</button>
<transition-group name="list" tag="ul">
// key值為item
<li v-for="(item,index) in items" :key="item" class="list-item" @click="deleteShow(index)">{{ item.text }}
// 給刪除按鈕再加個動畫 <transition name="move">
<button class="deleteButton" v-show="item.show" @click="deleteItem(index)">刪除</button>
</transition>
</li>
</transition-group>
</div>
</div>
</template>
看上面的代碼,其實就是和普通的transition是差不多的,只需理解為給每一個元素添加一個transition就行了,再看看樣式代碼:<style>
#movie{ margin-top:25px; width:100%; height:200px; display:flex; flex-direction: column; justify-content: flex-start; align-items: center; position:relative; } button{ left:50%; margin-left:-50px; position:relative; } .deleteButton { position:absolute; width:50px; height:30px; bottom:0; left:300px; } .list-item { position:relative; display: inline-block; width:300px; height:30px; margin:5px 40px; background:lightgrey; transition: all 0.5s linear; }
/*進入的初始狀態*/ .list-enter, .list-leave-active { opacity:0; transform: translateX(-300px); } /*列表平滑過渡*/
/*離開的狀態*/
.list-leave-active { transform: translateX(-300px); position:absolute } .move-enter,.move-leave-active{ transform: translate3d(50px,0,0); opacity: 0; } .move-enter-active,.move-leave-active{ opacity: 1; transition: all 0.2s linear; } </style>
看下結果,實現了一個最簡單<transition-group>:

最主要的是理解經歷的狀態以及狀態的變化,添加相應的樣式,就可以做出想要的效果了
