1.动画与过渡
过渡与动画的区别:
- 过渡:元素状态的变化。比如:一个块的颜色慢慢从红到蓝。
- 动画:元素位置的变化。比如:一个块从左边慢慢移动到右边。
1.1.动画
1.1.1.回顾CSS动画
下面是一个CSS3过渡效果。刷新时,在3秒钟时间内文字向右方移动后再回到原位置。
<style>
/* 定义动画规则 */
@keyframes boxanimate {
0% {
transform: translateX(0);
}
50% {
transform: translateX(50px);
}
100% {
transform: translateX(0);
}
}
.box{
/* 使用animation样式应用divanimate动画 */
animation: boxanimate 3s;
}
</style>
<body>
<div class="box">这是会动的文字</div>
</body>
1.1.2.在Vue中使用CSS动画
上面的动画在Vue中当然也是有效的。
但如果想使用Vue来控制动画的启动,就可以使用绑定class属性的方式。
<style>
...
</style>
<body>
<div id="app">
<div :class="{box:isAnimate}">这是会动的文字</div>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
Vue.createApp({
data() {
return {
isAnimate:true
}
}
}).mount('#app');
</script>
</body>
- 上面实例中,当isAnimate为true时,刷新时就会启用动画。
1.1.3.使用事件控制动画
还可以通过Vue事件来控制动画的启动和停止。
<style>
/* 定义动画规则 */
@keyframes boxanimate {
0% {
transform: translateX(0);
}
50% {
transform: translateX(50px);
}
100% {
transform: translateX(0);
}
}
.box{
/* 使用animation样式应用divanimate动画 */
animation: boxanimate 3s;
}
</style>
<body>
<div id="app">
<div :class="{box:isAnimate}" @mouseover="over" @mouseout="out">这是会动的文字</div>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
Vue.createApp({
data() {
return {
isAnimate:false
}
},
methods:{
over(){
this.isAnimate = true;
},
out(){
this.isAnimate = false;
}
}
}).mount('#app');
</script>
</body>
1.2.过渡
1.2.1.回顾CSS过渡
下面是一个CSS3过渡效果。当鼠标移动到文字上时,在3秒钟时间内背景颜色由红过渡到蓝色。
<style>
.box {
background-color: red;
/*持续时间为3秒*/
transition: 3s;
}
/*这里使用hover来触发过渡*/
div:hover {
background-color: blue;
}
</style>
<div class="box">这是会改变背景颜色的文字</div>
附录:常用过渡函数(默认值为ease函数):
- ease: 开始和结束慢,中间快。
- linear: 匀速。
- ease-in: 开始慢。
- ease-out: 结束慢。
- ease-in-out: 和ease类似,但比ease幅度大。
- step-start: 直接位于结束处。
- step-end: 位于开始处经过时间间隔后结束。
1.2.2.在Vue中实现过渡
在Vue中实现过渡效果时,由于需要触发过渡时机,所以需要绑定多个样式。
<style>
.box {
background-color: red;
/*持续时间为3秒*/
transition: 3s;
}
.boxblue {
background-color: blue;
}
</style>
<body>
<div id="app">
<div :class="{box:true,boxblue:isAnimate}" @mouseover="over" @mouseout="out">这是会改变背景颜色的文字</div>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
Vue.createApp({
data() {
return {
isAnimate: false
}
},
methods: {
over() {
this.isAnimate = true;
},
out() {
this.isAnimate = false;
}
}
}).mount('#app');
</script>
</body>
- 上面实例中,当鼠标悬停和移出时,实际上就是对象boxblue样式的切换使用。
2.入场出场的过渡与动画
上面学到的动画与过渡,实际应用最广泛的就是组件元素的入场动画和出场动画,这可以让组件元素切换时显得更加流畅,提升用户体验度。
比如,下面实例中,元素的显示和隐藏时非常直接,没有过渡,导致用户体验度差。
<body>
<div id="app">
<button @click="change">切换</button>
<mycomponent v-if="isShow"></mycomponent>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
Vue.createApp({
data() {
return {
isShow:false
}
},
methods:{
change(){
this.isShow = !this.isShow;
}
},
components:{
mycomponent:{
template: '<div>我是子组件</div>'
}
}
}).mount('#app');
</script>
</body>
因此,Vue中将动画与过渡进行了封装,以便让我们更快捷的实现入场出场动画。
2.1.过渡型入场出场
<style>
/*入场动画的开始状态*/
.v-enter-from {
opacity: 0;
}
/*入场动画的结束状态*/
.v-enter-to {
opacity: 1;
}
/*入场动画如何过渡*/
.v-enter-active {
transition: opacity 3s ease;
}
</style>
<body>
<div id="app">
<button @click="change">切换</button>
<!-- 使用transition标签包装需要动画的元素 -->
<transition>
<mycomponent v-if="isShow"></mycomponent>
</transition>
</div>
...
</body>
- 首先,需要将实现入场动画的元素用transition标签包裹。
- 然后,实现三个固定类名的样式,分别表示开始状态、结束状态、如何过渡。
接下来继续实现出场动画:
<style>
...
.v-leave-from {
opacity: 1;
}
.v-leave-to {
opacity: 0;
}
.v-leave-active {
transition: opacity 3s ease;
}
</style>
上面样式可以进行优化:
<style>
.v-enter-from {
opacity: 0;
}
.v-enter-to {
opacity: 1;
}
.v-enter-active,.v-leave-active {
transition: opacity 3s ease;
}
.v-leave-to {
opacity: 0;
}
.v-leave-active {
transition: opacity 3s ease;
}
</style>
- .v-leave-from可以省略
2.2.动画型入场出场
<style>
/*入场动画规则*/
@keyframes boxenter {
0% {
transform: translateX(-100px);
}
100% {
transform: translateX(0);
}
}
/*出场动画规则*/
@keyframes boxleave {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-100px);
}
}
/*这里应用入场动画规则*/
.v-enter-active {
animation: boxenter 3s;
}
/*这里应用出场场动画规则*/
.v-leave-active {
animation: boxleave 3s;
}
</style>
<body>
<div id="app">
<button @click="change">切换</button>
<!-- 使用transition标签包装需要动画的元素 -->
<transition>
<mycomponent v-if="isShow"></mycomponent>
</transition>
</div>
...
</body>
2.3.实现混合效果
将上面实例的样式结合起来,就可以实现元素既有过渡效果,又有动画效果。
<style>
.v-enter-from {
opacity: 0;
}
.v-enter-to {
opacity: 1;
}
.v-leave-to {
opacity: 0;
}
@keyframes boxenter {
0% {
transform: translateX(-100px);
}
100% {
transform: translateX(0);
}
}
@keyframes boxleave {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-100px);
}
}
.v-enter-active {
animation: boxenter 3s;
transition: opacity 3s ease;
}
.v-leave-active {
animation: boxleave 3s;
transition: opacity 3s ease;
}
</style>
2.4.列表动画
上面实例都是对单元素的入场与出场,但实际开发中很多时候都需要使用多元素(比如:列表)。那么Vue也封装了多元素的入场与出场。
<style>
@keyframes boxenter {
0% {
transform: translateX(-100px);
}
100% {
transform: translateX(0);
}
}
.v-enter-active {
animation: boxenter .5s;
}
</style>
<body>
<div id="app">
<transition>
<ul>
<!-- 将transition标签改为transition-group标签即可 -->
<transition-group>
<li v-for="item in arr" :key="item">{{item}}</li>
</transition-group>
</ul>
</transition>
<button @click="add">添加</button>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
Vue.createApp({
data() {
return {
arr: []
}
},
methods:{
add(){
this.arr.unshift(this.arr.length+1);
}
}
}).mount('#app');
</script>
</body>
上面代码中,需要做动画的元素是一个通过v-for遍历出来的一个列表。此时只要使用 transition-group 标签,就可实现列表出场动画。
但是,上面代码中,列表中的新元素是可以实现动画的,但原有元素还没有动画。我们可以通过增加 v-move样式来指定原有元素的动画。
<style>
@keyframes boxenter {
0% {
transform: translateX(-100px);
}
100% {
transform: translateX(0);
}
}
.v-enter-active {
animation: boxenter .5s;
}
/* 增加v-move样式 */
.v-move {
transition: all .5s ease;
}
</style>