Madogiwa Blog

主に技術系の学習メモに使っていきます。

Vue.js: Transitionでコンポーネントにanimationを設定するMEMO

最近、Vue.jsのTransitionを使う機会があったので使い方とかをMEMO📝

Transitionとは

Vue.jsのコンポーネントで簡単にアニメーションを設定できる仕組み。

vuejs.org

transitionで囲んだコンポーネントv-showv-ifといったコンポーネントの表示に関わる処理を検知して動的に該当コンポーネントの要素にclassを追加してくれる。

https://vuejs.org/guide/built-ins/transition.html#css-based-transitions

transitionname属性を付与することで設定されるclass名のprefixをコントロールすることができる。(デフォルトはv)

Named Transitions For a named transition, its transition classes will be prefixed with its name instead of v. For example, the applied class for the above transition will be fade-enter-active instead of v-enter-active. https://vuejs.org/guide/built-ins/transition.html#named-transitions

サンプルコード

以下が実際にTransitionを使って以下のアニメーションを付与してみたサンプルコードです。

  • 表示時に 右 -> 左のスライドイン
  • 非表示時に フェードアウト
<script setup>
import { ref } from 'vue'
const title = ref('Hello World!')
const body = ref('Hello World! Hello World! Hello World!')
const isShow = ref(true)
const handleOnClose = () => isShow.value = false
const handleOnShow = () => isShow.value = true

</script>

<template>
  <transition>
    <article class="message" v-show="isShow">
      <h3 class="message__title">
    {{ title }}
      </h3>
      <div class="message__body">
        <p class="message__body-text">
          {{ body }}
        </p>
      </div>
      <div class="message__footer">
        <button class="message__footer-button" @click="handleOnClose"> Close </button>
      </div>
    </article>
  </transition>
  <div>
    <br>
    <button @click="handleOnShow"> Open </button>
  </div>
</template>
<style scoped>
  .message {
    background-color: #eee;
    padding: 10px;
  }
  
  .message__title {
    margin: initial;
  }
  
  .message__footer {
    text-align: right;
  }
  
  .message__footer-button {
    border: none;
    cursor: pointer;
    outline: none;
    appearance: none;
    background-color: #fff;
    padding: 5px;
        box-shadow: 2px 2px 2px #ddd;
    border-radius: 10%;
  }
  

  .v-enter-from {
    opacity: 0;
    transform: translate(100%, 0);
  }

  .v-enter-active {
    transition: 0.6s cubic-bezier(0.16, 1, 0.3, 1);
  }

  .v-leave-active {
    transition: opacity 0.5s ease;
  }

  .v-leave-to {
    opacity: 0;
  }
</style>

また表示時には以下のサイトを参考にイージングを入れています。

easings.net

Transitionのイベントを取得する

Transitionを指定している場合、コンポーネントを表示したときにemitしたいといった場合にアニメーションの終了を待ちたいケースがありますが、その場合にはTransitionで各Eventをhookしてemitすることで適切なタイミングでイベントを発火させることができます。

You can hook into the transition process with JavaScript by listening to events on the component:

<Transition
  @before-enter="onBeforeEnter"
  @enter="onEnter"
  @after-enter="onAfterEnter"
  @enter-cancelled="onEnterCancelled"
  @before-leave="onBeforeLeave"
  @leave="onLeave"
  @after-leave="onAfterLeave"
  @leave-cancelled="onLeaveCancelled"

https://vuejs.org/guide/built-ins/transition.html#javascript-hooks

おわりに

よしなにイベントフックしてくれて簡単にアニメーションを設定できるTransition便利!✨

参考

qiita.com

stackoverflow.com