[Vue3] 命令型コンポーネントを作成する方法

公開日 2024年12月9日
更新日 2025年1月6日
7 分で読める
Vue

開発中、操作状態を表示するために全画面ローディングコンポーネント(例:フルスクリーンのローディング)が必要になることがよくあります。以下はシンプルな FullscreenLoading.vue コンポーネントの例です:



一般的には、ページのテンプレートにこのコンポーネントを使用し、変数でその表示・非表示を制御します:

<template>
  <FullscreenLoading v-if="showLoading" />
  <div class="wrapper">
    <button @click="clickHandler">Show Loading</button>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import FullscreenLoading from './components/FullscreenLoading.vue'

const showLoading = ref(false)

const clickHandler = () => {
  showLoading.value = true
  setTimeout(() => {
    showLoading.value = false
  }, 2000)
}
</script>

この方法は分かりやすいですが、複数のページで同じローディングロジックが必要な場合、各ページでコンポーネントをインポートし、状態を管理する必要のため、コードがたくさん重複してしまいます。

これを解決するために、ローディングロジックを命令型コンポーネントとしてカプセル化し、インポートや状態管理なしに簡単に呼び出せるようにします。

命令型コンポーネントを作成する

Vue の createApp メソッドを使用して、動的にコンポーネントインスタンスを作成し、DOM にマウントします:

import FullscreenLoading from '@/components/FullscreenLoading.vue'
import { createApp } from 'vue'

export function showLoading() {
  const app = createApp(FullscreenLoading)
  const container = document.createElement('div')

  app.mount(container)
  document.body.appendChild(container)

  return {
    close: () => {
      app.unmount()
      document.body.removeChild(container)
    },
  }
}

コードの説明

  1. コンポーネントインスタンスを動的に作成createApp を使用して、FullscreenLoading コンポーネントのインスタンスを作成します。
  2. DOM にマウント:div コンテナを作成し、そのコンポーネントインスタンスをマウントし、body に追加します。
  3. クローズ関数close 関数を返し、コンポーネントのアンマウントと DOM のクリーンアップを行います。これにより、メモリリークを防ぎます。

命令型コンポーネントを使用する

showLoading 関数を使用すると、コンポーネントや状態を明示的にインポートすることなく、全画面ローディングを簡単に表示できます:

<template>
  <div class="wrapper">
    <button @click="clickHandler">Show Loading</button>
  </div>
</template>

<script setup lang="ts">
import { showLoading } from './utils/loading.util'

const clickHandler = () => {
  const { close } = showLoading()
  
  setTimeout(() => {
    close()
  }, 2000)
}
</script>

showLoading を呼び出すと、ローディングコンポーネントが自動的に表示されます。閉じる場合は、showLoading が返す close 関数を呼び出します。この方法はシンプルで、複数ページでのコードの重複を回避できます。


まとめ

ローディングロジックを命令型コンポーネントとしてカプセル化することで、全画面ローディングインジケーターをより簡単に表示・非表示にできます。showLoading を呼び出すだけでローディングを表示でき、close 関数で非表示にできます。このカプセル化により、テンプレートの複雑さを軽減し、コンポーネントの再利用性が向上します。同様のシナリオでの動的 UI 操作に非常に適しています。

この内容が参考になれば幸いです!

概要

技術的洞察、経験、思考を共有する個人ブログ

クイックリンク

お問い合わせ

  • Email: hushukang_blog@proton.me
  • GitHub

© 2025 CODE赤兎. 無断転載禁止