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設計の自由度も高く、実用的な機能として展開できます。プロジェクト全体で統一感のあるモーダル設計を目指す際は、汎用コンポーネント化が大きな武器になります。