Nuxtのライフサイクルを完全に理解する - inokawablog

Nuxtのライフサイクルを完全に理解する

こちらの記事はvue.jsのライフサイクルを理解した上で読んでいただくとより一層理解が深まると思います。以下の記事を参考にしてください。

vue.jsのライフサイクルを完全に理解する

Nuxtのライフサイクルを理解する

下の画像がnuxtのライフサイクルになっています。公式から拝借しました。

  • nuxtServerInit
  • middleware
  • validate
  • asyncData / fetch

これらは全て満遍なく使用するのでしっかりと理解を深めましょう。

それでは、それぞれ見ていきましょう。

nuxtServerInit

serverInitと書いてあるようにこちらのnuxtServerInitはサーバーサイドに限り実行されます。主にサーバーサイドからクライアントサイドに直接渡したいデータがあるときに使用します。

※サーバーサイドでしか実行されないのでSPAモードにしていると動きません。

ではSPAモードではどうするのが良いのか。それはnuxtClientInitを使いましょう。こればこちらにまとまっておきましたのでそちらを見てください。

使用方法

nuxtServerInitstore/index.jsactionで使用します。

サーバーサイドから直接データをstoreにセットしたいときなどに使用します。

例として、サーバーサイドでセッションを持っていて、接続しているユーザーに req.session.user を通じてアクセスできるとします。認証されたユーザーにストアを渡すために store/index.js 下記のように書き換えます。

actions: {
  nuxtServerInit ({ commit }, { req }) {
    if (req.session.user) {
      commit('user', req.session.user)
    }
  }
}

middleware

severMiddlewareとしてexpress.jsを使っている場合もここで呼ばれます。 図では省略していますが、クライアントサイドでnuxt-linkをクリックして遷移したときは、ここまで戻って実行されます。

middlewareは主にユーザー認証に使用します。

ミドルウェアは middleware/ ディレクトリに入れます。 ファイル名がミドルウェアの名前となります(middleware/auth.jsauth ミドルウェアになります)

ユニバーサルモードの場合

ミドルウェアはサーバサイドでは一度だけ呼び出され(Nuxt アプリケーションへの最初のリクエスト時、またはページの再読込み時)クライアントサイドでは他のルートへ移動したときに呼び出されます。

SPA モードの場合

ミドルウェアはクライアントサイドで最初のリクエスト時と他のルートへ移動したときに呼び出されます。

以下に公式の例を示します。

middleware/authenticated.js:

ミドルウェアは第一引数として コンテキスト を受け取ります:

export default function ({ store, redirect }) {
  // ユーザーが認証されていないとき
  if (!store.state.authenticated) {
    return redirect('/login')
  }
}

pages/secret.vue

<template>
  <h1>シークレットページ</h1>
</template>

<script>
export default {
  middleware: 'authenticated'
}
</script>

また、特定のページにだけミドルウェアを使いたい場合、関数または配列の関数を直接使うことができます。

pages/secret.vue:

<template>
  <h1>Secret page</h1>
</template>

<script>
export default {
  middleware ({ store, redirect }) {
    // ユーザーが認証されていないとき
    if (!store.state.authenticated) {
      return redirect('/login')
    }
  }
}
</script>

ミドルウェアを使った実際の例を見たい場合は GitHub 上にある example-auth0 を参照してください。

validate

Nuxt.js では動的なルーティングを行うコンポーネント内でバリデーションメソッドを定義できます。

何をバリデートするかというと、

validate({ params, query, store }) {
  return true // params バリデーションを通過したとき
  return false // Nuxt.js がルートをレンダリングするのを中止して、エラーページを表示させる
}
async validate({ params, query, store }) {
  // await の処理
  return true // params バリデーションを通過したとき
  return false // Nuxt.js がルートをレンダリングするのを中止して、エラーページを表示させる
}

バリデーションメソッドが true を返さないときは Nuxt.js は自動的に 404 エラーページをロードします。

プロミスを返すこともできます:

validate({ params, query, store }) {
  return new Promise((resolve) => setTimeout(() => resolve()))
}

ルートのパラメータに対してバリデーションをかけたいときは、

export default {
  validate ({ params }) {
    // 数値でなければならない
    return /^\d+$/.test(params.id)
  }
}

さらに、storeに対してバリデートをかけたいときは、

export default {
  validate ({ params, store }) {
    // `params.id` が存在している category の id なのか否かをチェックする
    return store.state.categories.some(category => category.id === params.id)
  }
}

想定したエラーや想定外のエラーを投げることもできます!!便利!!

export default {
   async validate ({ params, store }) {
     // 500 internal server error とともにカスタムメッセージを投げる
     throw new Error('Under Construction!')
   }
}

asyncData / fetch

こちらは別の記事にまとめておいたのでそちらをご覧ください。

asyncData/fetchの違い

まとめ

ライフサイクルを理解することで開発のイメージが湧くかと思います。

NUXTはドキュメントが綺麗にまとまりすぎているので、ドキュメントの内容が多くなってしまいますが、自分なりに理解するのも大事だと思ったのでまとめて見ました。

NUXTにはまだまだ便利な機能があるので、次はそちらを紹介したいと思います。