Vue入门 - 过渡动画

189 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

对列表进行增删改查时,列表会出现动作,为这些动作加上过度动画,可以使应用更加精致。本文介绍CSS原生动画(过度)以及在Vue中如何绑定自定义动画,或者引入现有的动画库

准备一个卡片组件

image_BspkCJCLw1.png

  • 卡片HTML结构

    <template>
      <div class="page">
        <div class="card">
          <div class="card_header">
            <h3 class="card_title">
              {{name}}
            </h3>
            <div class="card_subtitle">
              Tansition & Animation
            </div>
          </div>
          <div class="card_content">
              <div class="emoji" >
                {{emoji}}
              </div>
          </div>
          <div class="card_action">
            <button>
              请按这里
            </button>
          </div>
        </div>
      </div>
    </template>
    
  • Css样式

     /* app.css*/
      .page{
        padding:32px;
        margin:32px;
      }
      .emoji{
        font-size: 80px;
      }
    /* card.css*/
      .card{
        display:flex;
        flex-direction:column;
        align-items:center;
        max-width:300px;
        box-sizing:border-box;
        padding: 32px;
        margin:0 auto;
        background: #f8f8f8;
        border-radius:10px;
      }
      .card_header{
        text-align:center;
        margin-bottom: 32px
      }
      .card_title{
        margin-bottom:8px
      }
      .card_subtitle{
        font-size:12px;
        color:#989898
      }
      .card_content{
        min-height:250px;
      }
      .card_action > button{
        outline:none;
        border:none;
        background: none;
        border: 2px solid #000;
        padding: 10px 24px;
        cursor:pointer;
        margin:4px
      }
      .card_action > button{
        outline:none;
        border:none;
        background: none;
        border: 2px solid #000;
        padding: 10px 24px;
        cursor:pointer;
        margin:4px
      }
      .card_action > button.active{
        background:#000;
        color:#fff
      }
    
    

基于Class的过渡与动画

过渡

为目标元素动态绑定Class,根据isActive的值来决定是否显示,再使用点击事件控制isActive 的状态

<script>
  export default {
    data(){
      return{
       isActive:false,
      }
    }
 }
</script>

<template>
 ...
  <div :class="['emoji',{hidden:'isActive'}]" >
      🌲
  </div>
 ...
  <button @click="isActive = !isActive">
      请按这里
  </button>
 ...
</template>

使用 .hidden的class类让元素透明度变成0,并为 .emoji 设置transition过渡属性,这样当点击按钮后会为emoji加上hidden的类,转换透明度时,具有过渡效果。

.emoji{
  font-size: 80px;
  transition: 0.5s
}
.hidden{
  opacity:0;
  transform:translateX(30px);
}

动画

定义动画

使用 @keyframes设置一个名为pulse的动画。此动画可以让元素放大1.5倍再变回原来的样式。

 @keyframes pulse{
    from {
      transform: scale3d(1,1,1);
    }
    50% {
      transform: scale3d(1.5,1.5,1.5);
    }
    to {
      transform: scale3d(1,1,1);
    }
  }

使用动画

定义一个类名为pulse,在animation-name的属性中绑定刚刚定义的动画。

.pulse{
    animation-name: pulse;
    animation-duration: 1s;
    animation-iteration-count: infinite;
  }

再把类绑定到元素上

<template>
 ...
  <div :class="['emoji',{pulse:'isActive'}]" >
      🌲
  </div>
 ...
  <button @click="isActive = !isActive">
      请按这里
  </button>
 ...
</template>

transition 组件的使用

在Vue中可以使用v-if属性决定元素是否显示,这种情况下不能使用class属性直接设置过渡和动画,需要使用到Vue提供的transition组件。

在使用此组件后,会在transition组件里面的元素出现或消失的时候加上一些类,我们可以通过这些类来为组件进行过渡或动画的效果

<template>
 ...
  <transition>
    <div v-if="isActive" class="emoji" >
      🌲
    </div>
  <transition>
 ...
  <button @click="isActive = !isActive">
      请按这里
  </button>
 ...
</template>

进入与离开过渡

进入的过渡

.v-enter-from{
    opacity: 0 ;
  }
  .v-enter-active{
    transition:0.3s;
  }
  .v-enter-to{
    opacity:1;
  }
 

离开的过渡

 .v-leave-from{
    opacity:1;
  }
  .v-leave-active{
    transition:0.3s;
  }
  .v-leave-to{
    opacity: 0 ;
  }

指定过渡效果的名称

transition组件添加 name的值,可以为指定名称。

<template>
 ...
  <transition name="slide">
    ...
  <transition>
 ...
</template>

指定名称后,在css中需要使用此名称控制具体的类

 /* 进入的效果 */
 .slide-enter-from{
    opacity: 0 ;
    transform:translateX(30px)
  }
  .slide-enter-active{
    transition:0.3s;
  }
  .slide-enter-to{
    opacity:1;
  }
 /* 移除的效果 */
  .slide-leave-from{
    opacity: 1 ;
  }
  .slide-leave-active{
    transition:0.3s;
  }
  .slide-leave-to{
    opacity:0;
    transform:translateX(30px)
  }

进入与离开的动画

同样可以在transition组件使用定义好的动画效果

<template>
 ...
  <transition name="pulse">
    ...
  <transition>
 ...
</template>

与过渡不同的是,只需要在active类下进行animation属性的绑定

.pulse-enter-active{
  animation: pulse 1s;
}
.pulse-leave-active{
  animation: pulse 1s;
}

自定义过渡类

可以直接使用第三方定义好的动画类。以导入animate.style库中的动画为例:

<style>
  @import './animate.css'
</style>

导入Css后,为transition自定义类的名称。

<template>
 ...
  <transition name="custom_classes" 
  enter-active-class="animate__animated animate__tada"
  leave-active-class="animate__animated animate__tada"  >
    ...
  <transition>
 ...
</template>

组件之间的过渡

需要在切换两个组件时使用动画效果,可以使用一个变量确定要显示那个组件,再把 <component> 组件放在transition组件当中。默认情况下切换组件时会有两个组件同时存在的情况,如需避免为transition 添加mode属性

<template>
 ...
  <transition name="custom_classes" 
  enter-active-class="animate__animated animate__tada"
  leave-active-class="animate__animated animate__tada"  
  mode="out-in"
  >
    ...
    <component :is="currentComponent"></component>
  <transition>
 ...
</template>



列表的过渡与动画

在为列表进行过渡效果时,需要把列表包装在transition-group组件中。组件同样有 name ,和自定义css属性名的属性。

在没有设置name 时,当列表切换顺序,会为两个item 添加 v-move的样式

<template>
 ...
  <transition-group name="slide" leave-active-class="animate__animated animate__tada" >
    <div v-for='emoji in emojis' :key='emoji' class="emoji">
      {{emoji}}
    </div>
  </transition-group>
 ...
</template>