# Vue动画
# CSS transition
在进入/离开的过渡中,会有 6 个 class 切换。
对于这些在过渡中切换的类名来说,如果使用一个没有名字的
<transition>
,则 v- 是这些类名的默认前缀。如果使用了<transition name="my-transition">
,那么 v-enter 会替换为 my-transition-enter。
v-enter
:定义进入过渡的开始状态。
v-enter-to
:2.1.8 版及以上定义进入过渡的结束状态。
v-enter-active
:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。
v-leave
:定义离开过渡的开始状态。
v-leave-to
:定义离开过渡的结束状态。
v-leave-active
:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。
<div id="app">
<transition name="fade">
<button v-if="visible">Button</button>
</transition>
<hr>
<button @click="visible=!visible">Click</button>
</div>
new Vue({
el:"#app",
data:{
visible: false
}
});
.fade-enter-active,.fade-leave-active{
transition: all 2s;
}
.fade-enter,.fade-leave-to{
opacity:0;
}
# CSS animation
<div id="example-2">
<button @click="show = !show">Toggle show</button>
<transition name="bounce">
<p v-if="show">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</transition>
</div>
new Vue({
el: '#example-2',
data: {
show: true
}
})
.bounce-enter-active {
animation: bounce-in .5s;
}
.bounce-leave-active {
animation: bounce-in .5s reverse;
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
使用第三方CSS动画库, 例如
animate.css
,在transition
中添加类即可
<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css">
<div id="example-3">
<button @click="show = !show">
Toggle render
</button>
<transition
name="custom-classes-transition"
enter-active-class="animated bounceInUp"
leave-active-class="animated bounceOutDown"
>
<p v-if="show">hello</p>
</transition>
</div>
new Vue({
el: '#example-3',
data: {
show: false
}
})
# JS 操作动画
使用第三方js库
Velocity
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
<div id="example-4">
<button @click="show = !show">
Toggle
</button>
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:leave="leave"
v-bind:css="false"
>
<p v-if="show">
Demo
</p>
</transition>
</div>
new Vue({
el: '#example-4',
data: {
show: false
},
methods: {
beforeEnter: function (el) {
el.style.opacity = 0
el.style.transformOrigin = 'left'
},
enter: function (el, done) {
Velocity(el, { opacity: 1, fontSize: '1.4em' }, { duration: 300 })
Velocity(el, { fontSize: '1em' }, { complete: done })
},
leave: function (el, done) {
Velocity(el, { translateX: '15px', rotateZ: '50deg' }, { duration: 600 })
Velocity(el, { rotateZ: '100deg' }, { loop: 2 })
Velocity(el, {
rotateZ: '45deg',
translateY: '30px',
translateX: '30px',
opacity: 0
}, { complete: done })
}
}
})
# 列表过度
同时渲染整个列表,使用 v-for 这种场景中,使用 <transition-group>
组件
组件特点:
- 默认为一个
<span>
。可以通过tag attribute
更换为其他元素 - 过渡模式不可用
- 内部元素总是需要提供唯一的 key attribute 值
- CSS 过渡的类将会应用在内部的元素中,而不是这个组/容器本身
<div id="list-demo" class="demo">
<button v-on:click="add">Add</button>
<button v-on:click="remove">Remove</button>
<transition-group name="list" tag="p">
<span v-for="item in items" v-bind:key="item" class="list-item">
{{ item }}
</span>
</transition-group>
</div>
.list-item {
display: inline-block;
margin-right: 10px;
}
.list-enter-active, .list-leave-active {
transition: all 1s;
}
.list-enter, .list-leave-to
/* .list-leave-active for below version 2.1.8 */ {
opacity: 0;
transform: translateY(30px);
}
new Vue({
el: '#list-demo',
data: {
items: [1,2,3,4,5,6,7,8,9],
nextNum: 10
},
methods: {
randomIndex: function () {
return Math.floor(Math.random() * this.items.length)
},
add: function () {
this.items.splice(this.randomIndex(), 0, this.nextNum++)
},
remove: function () {
this.items.splice(this.randomIndex(), 1)
},
}
})