动画基础
动画的实现方式
- 在CSS过度和动画中自动应用class(即transition)
- 配合第三方的动画库,如Animate.css
- 在过渡钩子中使用Javascript直接操作DOM
- 配合第三方Javascript动画库,如Velocity.js
补充 v-enter-active和v-enter-to是一起展示在元素中,一起离开元素中的 v-leave-active和v-leave-to是一起展示在元素中,一起离开元素中的
transition组件
<style>
/* 在元素进入的前一帧 */
.fade-enter {
opacity: 0;
}
/* 在元素进入到元素的终点样式 */
.fade-enter-active {
transition: opacity 1.5s;
}
/* 在元素离开最后的终点样式 */
.fade-leave-to {
opacity: 0
}
/* 在元素离开到元素的终点样式 */
.fade-leave-active {
transition: opacity 1.5s;
}
</style>
<div v-if="show">动画的展示隐藏<span @click="show = false">×</span></div>
new Vue({
el: "#app",
data: {
show: false
},
mounted (){
this.show = true;
}
})
使用CSS动画库
参考官方文档自定义过渡类名
例如:使用Animation.css
enter-active-class
和leave-active-class
是自定义transition组件的进入和离开的class,这个自定义class名称高于自动生成的类名
<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css">
<style>
.message {
background-color: red;
}
</style>
<div id="app">
<transition enter-active-class="animated bounceIn" leave-active-class="animated bounceOut">
<div v-if="show" class="message">
展示
</div>
</transition>
<button @click="show = !show">toggle</button>
</div>
new Vue({
el: '#app',
data: {
show: false
}
})
JS动画钩子
<style>
.message {
background-color: red;
}
.fade-enter-active {
transition: opacity 1.5s;
}
.fade-leave-active {
transition: opacity 1.5s;
}
</style>
<div id="app">
<transition name="fade" @before-enter="beforeEnter" @enter="enter" @leave="leave" @before-leave="beforeLeave">
<div v-if="show" class="message">
展示
</div>
</transition>
<button @click="show = !show">toggle</button>
</div>
new Vue({
el: '#app',
data: {
show: false
},
methods: {
beforeEnter (el) {
el.style.opacity = 0; // 设置初始状态
},
enter (el, done) {
document.body.offsetHeight; // 触发回流激活动画
el.style.opacity = 1; // 设置结束状态
// 监听动画的结束事件,并执行done函数(不执行done函数,则动画不会结束,还占页面位置)
// 合理的还需要在之后动画结束remove监听
el.addEventListener('transitionend', done)
},
leave (el, done) {
el.style.opacity = 0;
// 监听动画的结束事件,并执行done函数(不执行done函数,则动画不会结束,还占页面位置)
// 合理的还需要在之后动画结束remove监听
el.addEventListener('transitionend', done)
},
beforeLeave (el) {
document.body.offsetHeight; // 触发回流激活动画
el.style.opacity = 1;
}
}
})
纯JS方案(Velocity.js使用)
<div id="app">
<transition @before-enter="beforeEnter" @enter="enter" @leave="leave" @before-leave="beforeLeave">
<div v-if="show" class="message">
展示
</div>
</transition>
<button @click="show = !show">toggle</button>
</div>
new Vue({
el: '#app',
data: {
show: false
},
methods: {
beforeEnter (el) {
el.style.opacity = 0;
},
enter (el, done) {
// 不需要回流,因为内部已经做了
Velocity(el, { opacity: 1 }, {duration: 500, complete: done })
},
beforeLeave (el) {
el.style.opacity = 1;
},
leave (el, done) {
Velocity(el, { opacity: 0 }, {duration: 500, complete: done })
}
}
})
列表动画
使用transition-group
组件对v-for
的元素包裹起来
原理是在transition-group
包裹的标签中每一个元素都添加了transition
组件
<style>
.fade-enter {
opacity: 0;
}
.fade-enter-active {
transition: opacity 1.5s
}
.fade-leave-to {
opacity: 0;
}
.fade-leave-active {
transition: opacity 1.5s
}
</style>
<div id="app">
<button @click="list.push('====')">增加</button>
<ul>
<transition-group name="fade">
<li v-for="(item, i) in list" :key="i">
{{item}}
</li>
</transition-group>
</ul>
<button @click="show = !show">收缩</button>
<transition name="fade">
<div v-if="show">25614564564</div>
</transition>
</div>
<script>
new Vue({
el: '#app',
data: {
list: [
'test',
'web'
],
show: false
}
})
</script>