brand logo

ドキュメント

イベント

Nuxtはhookableによって強力なイベントシステムを提供します。

イベント

イベントを使用することは、アプリケーションを疎結合にし、コードの異なる部分間でより柔軟でモジュール化された通信を可能にする素晴らしい方法です。イベントには、互いに依存しない複数のリスナーを持たせることができます。例えば、注文が発送されるたびにユーザーにメールを送信したい場合、注文処理コードをメールコードに結びつける代わりに、リスナーが受信してメールを送信するためのイベントを発行することができます。

Nuxtのイベントシステムは、Nuxtのフックシステムを支えるのと同じライブラリである unjs/hookable によって動作しています。

イベントとリスナーの作成

hook メソッドを使用して独自のカスタムイベントを作成できます:

const nuxtApp = useNuxtApp()

nuxtApp.hook('app:user:registered', payload => {
  console.log('新しいユーザーが登録されました!', payload)
})

イベントを発行してリスナーに通知するには、callHook を使用します:

const nuxtApp = useNuxtApp()

await nuxtApp.callHook('app:user:registered', {
  id: 1,
  name: 'John Doe',
})

ペイロードオブジェクトを使用して、発行者とリスナー間の双方向通信を可能にすることもできます。ペイロードは参照渡しされるため、リスナーがそれを変更して発行者にデータを返すことができます。

const nuxtApp = useNuxtApp()

nuxtApp.hook('app:user:registered', payload => {
  payload.message = '私たちのアプリへようこそ!'
})

const payload = {
  id: 1,
  name: 'John Doe',
}

await nuxtApp.callHook('app:user:registered', {
  id: 1,
  name: 'John Doe',
})

// payload.message は '私たちのアプリへようこそ!' になります

Nuxt DevTools のフックパネルを使用してすべてのイベントを確認できます。

型の拡張

Nuxtが提供するフックの型を拡張することができます。

import { HookResult } from "@nuxt/schema";

declare module '#app' {
  interface RuntimeNuxtHooks {
    'your-nuxt-runtime-hook': () => HookResult
  }
  interface NuxtHooks {
    'your-nuxt-hook': () => HookResult
  }
}

declare module 'nitropack' {
  interface NitroRuntimeHooks {
    'your-nitro-hook': () => void;
  }
}

tips

このセクションは公式ドキュメントの翻訳ではなく、本サイト独自の補足記事です。

Nuxtのイベントシステムを活用するための実践ガイド

Nuxtのイベントシステムは、アプリケーション内の異なるモジュールやコンポーネント間で柔軟かつ疎結合な通信を可能にします。これにより、機能ごとにコードを分離しやすくなり、保守性や拡張性が向上します。特に大規模なプロジェクトや複数人での開発においては、イベントを活用することでコードの依存関係を減らし、変更の影響範囲を限定できるため非常に有用です。

本記事では、Nuxtのイベントシステムの基本的な使い方から、実務でよくあるユースケース、注意すべきポイントまでを丁寧に解説します。初級から中級の開発者が理解しやすいように、具体例を交えながら説明します。


まず結論:Nuxtのイベントシステムの要点

  • Nuxtのイベントは hookcallHook メソッドで作成・発行できる
  • イベントは複数のリスナーを持てるため、機能を分離しやすい
  • ペイロードは参照渡しされ、リスナー側で変更可能(双方向通信が可能)
  • 型定義を拡張して独自イベントの型安全性を高められる
  • Nuxt DevToolsのフックパネルでイベントの発火状況を確認できる

いつ使うべきか? 使わない方がよいケースは?

使うべきケース

  • 機能間の疎結合な連携が必要なとき
    例えば、ユーザー登録処理とメール送信処理を分離したい場合。イベントを使うことで、登録処理はメール送信の詳細を知らずに済みます。

  • 複数の処理を同時にトリガーしたいとき
    1つのイベントに複数のリスナーを登録し、それぞれ異なる処理を実行できます。

  • プラグインやモジュール間の通信
    Nuxtのプラグインやモジュールが互いに依存せず連携する際に便利です。

使わない方がよいケース

  • 単純な同期処理や直接呼び出しで十分な場合
    イベントを使うとコードが複雑になることもあるため、単純な関数呼び出しで済むならそちらを優先しましょう。

  • 大量のイベント発火がパフォーマンスに影響する場合
    頻繁に発火するイベントはパフォーマンス低下の原因になることがあるため、必要性をよく検討してください。


実務でよくあるユースケースとサンプルコード

1. ユーザー登録後にウェルカムメールを送信する

ユーザー登録処理とメール送信処理を分離し、イベントで連携します。

// ユーザー登録処理側
const nuxtApp = useNuxtApp()

async function registerUser(userData) {
  // 登録処理(DB保存など)
  // ...

  // 登録完了イベントを発火
  await nuxtApp.callHook('app:user:registered', userData)
}
// メール送信処理側(リスナー登録)
const nuxtApp = useNuxtApp()

nuxtApp.hook('app:user:registered', (user) => {
  // メール送信ロジック
  console.log(`Welcome email sent to ${user.email}`)
})

2. ペイロードを変更して双方向通信を実現する

リスナーがペイロードにメッセージを追加し、発行者が受け取る例です。

const nuxtApp = useNuxtApp()

nuxtApp.hook('app:user:registered', (payload) => {
  payload.message = 'ようこそ!'
})

const payload = { id: 1, name: 'Taro' }
await nuxtApp.callHook('app:user:registered', payload)

console.log(payload.message) // 'ようこそ!'

3. 複数の機能を同時にトリガーする

1つのイベントに複数のリスナーを登録し、ログ記録やキャッシュ更新などを同時に行う例。

const nuxtApp = useNuxtApp()

nuxtApp.hook('app:data:updated', () => {
  console.log('データが更新されました')
})

nuxtApp.hook('app:data:updated', () => {
  // キャッシュクリア処理
  console.log('キャッシュをクリアしました')
})

// イベント発火
await nuxtApp.callHook('app:data:updated')

よくある落とし穴・注意点

SSRとCSRの違いに注意

Nuxtはサーバーサイドレンダリング(SSR)とクライアントサイドレンダリング(CSR)の両方をサポートしていますが、イベントの発火タイミングやリスナーの登録場所によっては期待通りに動作しないことがあります。特にサーバーとクライアントで同じイベントを使う場合は、どちらの環境で処理が走るかを意識しましょう。

Hydration(ハイドレーション)時のイベント

クライアント側でのハイドレーション中にイベントを発火すると、状態の不整合や二重処理が起こる可能性があります。必要に応じて、クライアント専用の処理は process.client などで制御してください。

パフォーマンスへの影響

イベントは便利ですが、頻繁に大量のイベントを発火するとパフォーマンスに悪影響を及ぼすことがあります。特に重い処理をリスナーに登録する場合は注意が必要です。

型定義の拡張を活用する

独自イベントを多用する場合は、型定義を拡張して型安全に管理しましょう。これにより、イベント名の誤字やペイロードの型ミスを防げます。


まとめ

Nuxtのイベントシステムは、アプリケーションの疎結合化と柔軟な機能連携を実現する強力なツールです。hookcallHook を使って簡単にイベントを作成・発火でき、複数のリスナーで処理を分散できます。実務ではユーザー登録後のメール送信や複数処理の同時実行などに活用されることが多いです。

ただし、SSR/CSRの違いやパフォーマンス面の注意も必要です。型定義の拡張も活用しつつ、適切にイベントを設計することで、より保守性の高いNuxtアプリケーションを構築できます。


Nuxt DevToolsのフックパネルを使うと、発火したイベントや登録されているリスナーを視覚的に確認できるため、デバッグや開発効率の向上に役立ちます。