【Vue.js】アニメーション付きアコーディオンを実装する方法|transitionとrefを活用

【Vue.js】アニメーション付きアコーディオンを実装する方法|transitionとrefを活用 Vue.js

Vue.jsでは、アコーディオンの開閉を簡単に実装できますが、より自然な動きを実現するためにはアニメーションの工夫が重要です。本記事では、<transition>タグとrefを組み合わせて、スムーズに開閉するアニメーション付きアコーディオンの作り方を解説します。

アコーディオンの基本構成

まずは、Vueコンポーネント内でアコーディオンの開閉状態を管理するために、isOpenという状態を用意します。

<template>
  <div class="accordion">
    <button @click="toggle">{{ isOpen ? '閉じる' : '開く' }}</button>
    <transition
      name="accordion"
      @enter="onEnter"
      @after-enter="onAfterEnter"
      @leave="onLeave"
      @after-leave="onAfterLeave"
    >
      <div v-show="isOpen" ref="content" class="accordion-content">
        <p>ここにアコーディオンの中身を記述します。</p>
      </div>
    </transition>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isOpen: false,
    };
  },
  methods: {
    toggle() {
      this.isOpen = !this.isOpen;
    },
    onEnter(el) {
      el.style.height = '0px';
      el.offsetHeight; // 再描画を強制
      el.style.transition = 'height 0.3s ease';
      el.style.height = el.scrollHeight + 'px';
    },
    onAfterEnter(el) {
      el.style.height = 'auto';
    },
    onLeave(el) {
      el.style.height = el.scrollHeight + 'px';
      el.offsetHeight;
      el.style.transition = 'height 0.3s ease';
      el.style.height = '0px';
    },
    onAfterLeave(el) {
      el.style.height = 'auto';
    },
  },
};
</script>

<style scoped>
.accordion-content {
  overflow: hidden;
}
.accordion-enter-active,
.accordion-leave-active {
  transition: height 0.3s ease;
}
</style>

アニメーションのポイント

Vueの<transition>はクラスベースだけでなく、JavaScriptフックを使ったアニメーション制御も可能です。今回のようにheightをスムーズに変化させる場合、明示的にスタイルを設定しながら開閉のタイミングで処理を分けることがポイントです。

refを使う理由

ref="content"でDOM要素を参照し、el.scrollHeightを使って動的に高さを取得しています。これにより、コンテンツのサイズに応じたアニメーションが実現可能になります。

まとめ

Vue.jsでアニメーション付きアコーディオンを実装するには、<transition>のJavaScriptフックとrefによるDOM操作が鍵となります。スタイル制御を組み合わせることで、ユーザーにとって自然な動きのUIが実現できます。

動的にサイズが変わるコンテンツや複数アコーディオンがある場合でも、同様の仕組みを活用することで柔軟に対応できます。ぜひプロジェクトに応じた実装を試してみてください。