在
vue
中给组件或元素添加动画的方式可以分为多种,但总体无非还是通过
css
和
JavaScript
来进行处理
我们通过代码来看一下
- css动画
- js动画
- vue动画
css动画
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.js_animation_box {
width: 100px;
height: 100px;
background: red;
transition: .5s all;
}
.js_animation_box.end {
width: 200px;
height: 200px;
background: green;
}
</style>
</head>
<body>
<button id="js_animation_btn">原生动画</button>
<div id="js_animation_box" class="js_animation_box"></div>
<script>
// 原生 + css
let jsAnimationBtn = document.querySelector('#js_animation_btn');
let jsAnimationBox = document.querySelector('#js_animation_box');
jsAnimationBtn.onclick = function() {
jsAnimationBox.classList.add('end');
}
</script>
</body>
</html>
js动画
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.js_animation_box {
width: 100px;
height: 100px;
background: red;
}
</style>
</head>
<body>
<button id="js_animation_btn">原生动画</button>
<div id="js_animation_box" class="js_animation_box"></div>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script>
// jq
$('#js_animation_btn').on('click', function() {
$('#js_animation_box').animate({
width: 200,
height: 200
}, .5);
});
</script>
</body>
</html>
vue动画
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.js_animation_box {
width: 100px;
height: 100px;
background: red;
transition: .5s all;
}
.js_animation_box.end {
width: 200px;
height: 200px;
background: green;
}
</style>
</head>
<body>
<div id="app">
<button @click="isEnd = !isEnd">vue动画</button>
<div :class="['js_animation_box', isEnd ? 'end' : '']"></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
isEnd: false
}
});
</script>
</body>
</html>
对比三份代码,我们可以看出vue动画,还是需要一些css和js来处理
transition 组件
通过
transition
组件包裹的元素或组件,会触发过渡,并添加指定的
class
样式
...
<transition name="slide-fade">
<component :is="currentComponent"></component>
</transition>
...
这里的name就是一个有动画效果的类名,绑定上来之后可以在后续加上条件
-
v-enter
:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除 -
v-enter-active
:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数 -
v-enter-to
:
2.1.8版及以上
定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时
v-enter
被移除),在过渡/动画完成之后移除 -
v-leave
: 定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除 -
v-leave-active
:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数 -
v-leave-to
:
2.1.8版及以上
定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时
v-leave
被删除),在过渡/动画完成之后移除
我们可以通过代码来看
<style>
...
.slide-fade-enter {
opacity: 0;
}
.slide-fade-enter-to {
opacity: 1;
}
.slide-fade-enter-active {
transition: all 3s ease;
}
</style>
.slide-fade-enter
动画开始时执行的
.slide-fade-enter-to
动画结束时执行的
.slide-fade-enter-active
像是一个总控一样,可以写一些过度,比如说执行时间,运动速度,播放次数之类的
然后我们可以通过下图,更加直观的了解vue动画的上述指令
上边都说的是进入,我们现在可以加上离开,而且方式很简单
<style>
...
.slide-fade-enter,.slide-fade-leave-to{
opacity: 0;
}
.slide-fade-enter-to,.slide-fade-leave{
opacity: 1;
}
.slide-fade-enter-active,.slide-fade-leave-active{
transition: all 3s ease;
}
</style>
现在我们就加上离开了,是不是很神奇!
其实我们先就可以看出来,vue没有自己的动画,他只是在css3动画上多了一个控制器而已!
触发方式
-
条件渲染 (使用
v-if
) -
条件展示 (使用
v-show
) - 动态组件
- 组件根节点
结合Animate.css动画库
<template>
<div id="app">
<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css">
<button @click="goto('InBox')" :class="{ current: currentComponent === 'InBox' }">收邮件</button>
<button @click="goto('PostMail')" :class="{ current: currentComponent === 'PostMail' }">发邮件</button>
<button @click="goto('RecycleBin')" :class="{ current: currentComponent === 'RecycleBin' }">垃圾箱</button>
<hr />
<transition
name="custom-classes-transition"
enter-active-class="animated pulse"
leave-active-class="animated bounceInUp"
>
<component :is="currentComponent"></component>
</transition>
<hr />
</div>
</template>
<script>
import InBox from "./components/InBox.vue";
import PostMail from "./components/PostMail.vue";
import RecycleBin from "./components/RecycleBin.vue";
export default {
name: "App",
data() {
return {
currentComponent: "InBox"
};
},
components: {
InBox,
PostMail,
RecycleBin
},
methods: {
goto(target) {
this.currentComponent = target;
}
}
};
</script>
<style>
.current {
background: yellow;
}
</style>