Vue使用过渡类名实现动画
什么是过渡类名和组件transition
首先我们需要了解动画的本质,动画就是一个元素或者组件从一种状态进入/离开到另一种状态的整个过程(包括动画的开始状态和结束状态)。比如,v-show和v-if所实现的功能就是一种动画——元素从显示到隐藏的相互转换。
在Vue中在动画进入/离开的过渡中,规定会有 6 个 class 切换。
1、v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
2、v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
3、v-enter-to:2.1.8 版及以上定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。
4、v-leave:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
5、v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
6、v-leave-to:2.1.8 版及以上定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。
为了和普通的动画做区别,Vue特意用一个 transition 将需要动画的部分包裹,表示可以使用以上的 6 个 class 切换。
<transition>
<h1 v-if="flag">Hello</h1>
</transition>
过渡类动画实例
现在我们了解了什么是过渡类名和transition的概念和作用,以下用一个实例帮助我们了解使用过渡类名实现动画的具体实现方式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vueApp</title>
<!-- 自定义两组样式,来控制 transition 内部的实现动画 -->
<style>
/* v-enter 【这是一个时间点】 是进入之前, 元素的起始状态, 此时还没有进入*/
/* v-leave-to 【这是一个时间点】 是动画离开之后, 离开的终止状态, 此时元素 动画已经结束了*/
.v-enter,
.v-leave-to {
opacity: 0;
transform: translateX(150px);
}
/* v-enter-active 【入场动画的时间段】 */
/* v-leave-active 【离场动画的时间段】 */
.v-enter-active,
.v-leave-active {
transition: all 0.8s ease;
}
</style>
</head>
<body>
<div id="app">
<button @click="flag = !flag">显示/隐藏</button>
<transition>
<h1 v-if="flag">Hello</h1>
</transition>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
flag: false
},
methods: {
}
});
</script>
</body>
</html>
动画实现了h1元素透明度和位置的过渡转换。
自定义过渡类动画名称
上面提到的实例直接使用transition将动画包裹,不做任何区别修饰,这样,当我们想实现多个不同的动画时该怎么办?这样不会乱吗?能不能给不同的transition提供不同的名字,用来实现不同的动画呢?像这样:
<transition name="toggle1">
<h1 v-if="flag1">Hello</h1>
</transition>
然后类名改成:
.toggle1-enter,
.toggle1-leave-to,
.toggle1-enter-active,
.toggle1-leave-active,
.toggle1-enter-to,
.toggle1-leave
Vue也想到这一点,并且真的这么做了。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vueApp</title>
<!-- 自定义两组样式,来控制 transition 内部的实现动画 -->
<style>
/* v-enter 【这是一个时间点】 是进入之前, 元素的起始状态, 此时还没有进入*/
/* v-leave-to 【这是一个时间点】 是动画离开之后, 离开的终止状态, 此时元素 动画已经结束了*/
.toggle1-enter,
.toggle1-leave-to {
opacity: 0;
transform: translateX(150px);
}
.toggle2-enter,
.toggle2-leave-to {
opacity: 0;
transform: translateY(150px);
}
/* v-enter-active 【入场动画的时间段】 */
/* v-leave-active 【离场动画的时间段】 */
.toggle1-enter-active,
.toggle1-leave-active {
transition: all 0.8s ease;
}
.toggle2-enter-active,
.toggle2-leave-active {
transition: all 0.8s ease;
}
</style>
</head>
<body>
<div id="app">
<button @click="flag1 = !flag1">显示/隐藏</button>
<transition name="toggle1">
<h1 v-if="flag1">Hello</h1>
</transition>
<hr>
<button @click="flag2 = !flag2">显示/隐藏</button>
<transition name="toggle2">
<h1 v-if="flag2">Hello</h1>
</transition>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
flag1: false,
flag2: false
},
methods: {
}
});
</script>
</body>
</html>