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