【Vue.js】ダイアログやモーダルをコンポーネント化して再利用する方法

【Vue.js】ダイアログやモーダルをコンポーネント化して再利用する方法 Vue.js

Vue.jsでアプリケーションを構築する際、ダイアログやモーダルウィンドウはユーザーとの重要なインターフェースになります。単発の実装ではなく、複数の場面で再利用可能な汎用モーダルコンポーネントとして設計することで、保守性と再利用性が大きく向上します。この記事では、Vue 3のComposition APIを使ってモーダルをコンポーネント化し、柔軟に使い回す方法を解説します。

モーダルコンポーネントの作成

まずは、ベースとなるモーダルコンポーネントを作成します。<Modal.vue>というファイルを用意し、表示状態とスロットによる柔軟な中身の差し替えに対応します。

<template>
  <div v-if="visible" class="modal-overlay" @click.self="close">
    <div class="modal-content">
      <slot />
      <button @click="close">閉じる</button>
    </div>
  </div>
</template>

<script setup>
import { defineProps, defineEmits } from 'vue'

const props = defineProps({
  visible: Boolean
})
const emit = defineEmits(['close'])

function close() {
  emit('close')
}
</script>

<style scoped>
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0,0,0,0.5);
  display: flex;
  justify-content: center;
  align-items: center;
}
.modal-content {
  background: #fff;
  padding: 20px;
  border-radius: 8px;
}
</style>

モーダルを呼び出す親コンポーネント

次に、このモーダルを実際に使用する側のコンポーネントを作成します。

<template>
  <button @click="isOpen = true">モーダルを開く</button>

  <Modal :visible="isOpen" @close="isOpen = false">
    <h2>確認メッセージ</h2>
    <p>本当に削除しますか?</p>
  </Modal>
</template>

<script setup>
import { ref } from 'vue'
import Modal from './Modal.vue'

const isOpen = ref(false)
</script>

この構成により、任意のコンテンツをスロットで挿入でき、同じモーダルコンポーネントを様々なシーンで使い回せます。

再利用性を高める工夫

さらに再利用性を高めるには、以下のような工夫が有効です:

  • タイトル・ボタン文言をprops化する
  • OK/キャンセルのemitイベントを分ける
  • アニメーションやescキー閉じ処理の追加

たとえば次のようにpropsでカスタマイズできる汎用モーダルに進化させると、業務アプリでも十分活用できます。


<Modal :visible="isOpen" title="警告" @confirm="handleOk" @cancel="handleCancel">
  本当に削除しますか?
</Modal>

まとめ

Vue.jsでは、ダイアログやモーダルをコンポーネントとして切り出すことで、再利用性が高まり開発効率が向上します。スロットやprops、イベント発火の仕組みを活用すれば、UI設計の自由度も高く、実用的な機能として展開できます。プロジェクト全体で統一感のあるモーダル設計を目指す際は、汎用コンポーネント化が大きな武器になります。