
今回はNuxt.jsのライフサイクルフックを丁寧に解説します。
Nuxt.jsはじめたばかりの方は、間違いなくといっていいほどライフサイクルフックでつまづくと思います。



多分ライフサイクルフックを理解してないことに原因があるかも。
初心者あるあるですね。
図解しながら解説していきます。
この記事で分かること



そもそもNuxt.jsのライフサイクルフックとは?
ライフサイクルフックというのは、「Nuxt.jsがページを表示する手順」のことです。
ページ表示するまでにこういう手順を踏むから、それにあわせてイベントとか登録してねー、ていう感じです。
ライフサイクルフックの全体像はこんな感じ。
これはNuxt.js公式サイトに書いてあるライフサイクルフックを、より細かくわけたものです。
省略されているものもあったので、いくつか付け足してます。



Nuxt.jsの各フックの特徴と適切なコーディングの仕方
・Nuxt.jsの各フックの概要
・どういう風にコーディングしていけば良いのか?
といったところを解説していきます。
serverMiddleware
serverMiddlewareはサーバーのみで実行されるフックです。
ここではサーバー固有の処理を書きます。
たとえばAPIサーバーを作ったりできます。
具体的なやり方はこちらの記事を参考に。


APIとは何ぞや?という方にすごいザックリと解説すると、「データを返してくれるサーバー」のことです。
そのAPIサーバーをserverMiddlewareで作ることもできるってことですね。
使い方は処理を書いたファイルを、nuxt.config.jsファイルのserverMiddlewareに登録するだけです。
公式のサンプルはこんな感じ。
export default function (req, res, next) {
// req は Node.js の HTTP リクエストオブジェクトです
console.log(req.url)
// res は Node.js の HTTP レスポンスオブジェクトです
// next は 次のミドルウェアを呼び出すための関数です。
// ミドルウェアがエンドポイントでない場合、関数の最後で next を呼び出すのを忘れないでください!
next()
}
serverMiddleware: ['~/server-middleware/logger']
参考サイトはこちら。
serverMiddlewareとRouteMiddlewareの違いについても言及されています。
nuxtServerInit
こちらもサーバー側でのみ実行されるフックです。
ここではあらかじめ初期値を渡す操作を書いたり、ログイン認証したりするコードを書きます。
つまり「クライアントサイドに処理を渡す前にサーバーでやっておかなきゃ!」な処理を書くわけですね。
使い方はstore/index.jsにnuxtServerInitアクションを追加するだけ。
公式のサンプルはこんな感じ。
actions: {
nuxtServerInit ({ commit }, { req }) {
if (req.session.user) {
commit('user', req.session.user)
}
}
}
ちなみにCookieに保存したデータを取り出したいときも、
const cookie = req.headers.cookie
と書けばかんたんに取り出せます。
参考サイトはこちら。


RouteMiddleware
これはサーバー・クライアントどちらでも実行されるフックです。
サーバーで1回、クライアントではページ遷移のたびに呼ばれます。
名前どおりルーティング制御、つまり「認証されていないユーザーはこのページにはいかせないぞ!」的な処理も書けるわけです。
使い方はmiddlewareディレクトリの中にファイルを作成し、
①nuxt.config.js
②layout
③page
のどれかに登録するだけです。上の方が適用される優先順位が高いです。
公式のサンプルはこんな感じ。
export default function (context) {
// userAgentプロパティをコンテキストに追加します
context.userAgent = process.server
? context.req.headers['user-agent']
: navigator.userAgent
}
export default {
//nuxt.config.jsでの登録
router: {
middleware: 'sample'
}
}
参考サイトはこちら。


validate
これもサーバーではSSR時に1回、クライアントではページ遷移のたびに呼ばれます。
使いたいコンポーネント内で、validateメソッドを追加すれば良いだけです。
このvalidateでエラーが出たときは、自動的にエラーページが表示されます。
公式のサンプルはこんな感じ。
動的に変化するURLのチェックができたりするんですね。
export default {
validate({ params }) {
// 数字でなければなりません。違ったら自動的にエラーページに遷移。
return /^\d+$/.test(params.id)
}
}
参考サイトはこちら。
asyncData
SSR時にサーバーで1度、クライアントではページが読み込まれるたびに行われるメソッドです。
asyncDataメソッドは、APIなどからデータを取得し、ローカルデータに格納する時に使われます。
あとからfetchという似たようなメソッドが出てきますが、違いはfetchのセクションで説明します。
使い方は、使いたいコンポーネント内でasyncDataメソッドを追加するだけです。
公式のサンプルはこちら。
async asyncData({ $http }) {
const mountains = await $http.$get('https://api.nuxtjs.dev/mountains')
return { mountains }
}
参考サイトはこちら。
beforeCreate
Vueインスタンスが初期化される時に呼び出されるフックです。
インスタンスが初期化されるが、データにはまだアクセスできません。
つまりthisを使って、
this.data = data;
みたいにローカルデータに、何か代入することはこの段階ではできません。
参考サイトはこちら。
created
こちらはVueインスタンスが初期化されたあと、データも初期化されたときに呼ばれます。
なのでここではじめて、
this.data = data;
のようにthisが使えます。
参考サイトはこちら。
fetch
サーバーではSSR時に1度、クライアントではページを遷移するたびに呼ばれるメソッドです。
fetchメソッドはAPIなどからデータを取得する時に使われます。
先ほどasyncDataという似たようなメソッドが出てきましたが、何が違うかというと、
ということです。全く意味わかりませんね。
解説します。
fetchはcreatedの後に、asyncDataはcreatedの前に位置するフックでした。
createdのあとからローカルデータにアクセスできるということも先ほど解説しましたね。
ということは、fetchはローカルデータにアクセスでき、asyncDataはアクセスできません。
なのでasyncDataはAPIからデータをとってきて、それをローカルデータにマージ(統合)する、という手法をとっています。
たとえば以下のasyncDataとfetchのサンプルでは、同じようにAPIからデータをとってきて、それをローカルデータのtodosに入れています。
export default {
async asyncData(context) {
const data = await context.$axios.$get(
`https://jsonplaceholder.typicode.com/todos`
)
// todosはローカルデータに定義されていなくてOK。
return { todos: data.Item }
// todosはローカルにマージされます。
}
}
export default {
data() {
return {
todos: []
}
},
async fetch() {
const { data } = await axios.get(
`https://jsonplaceholder.typicode.com/todos`
)
// todosはローカルデータに定義されている必要あり。
this.todos = data
}
}
fetchではしっかり、thisにアクセスしているのがわかりますね。
もともとtodosを定義している必要もあります。
これがasyncDataとfetchの主な違いです。
参考サイトはこちら。


beforeMount
Vueインスタンスが実際にDOMにマウント(結合)される前に、クライアントのみで呼び出されるフックです。
サーバーでは呼び出されません。
自分はここで特に操作を書いたことはないので、体験談をお話しすることはできません。(スマソ。。。)
DOMに反映される前になにかアレコレしたいときに、こっちに書くのかな、と思います。
参考サイトはこちら。
mounted
VueインスタンスがDOMにマウントされた後に、クライアントで呼ばれます。
beforeMountと同じように、サーバーでは呼ばれません。
DOMが作られているので、DOMの操作を書くことが出来ます。
つまりidやclassを指定して要素を取得したりもここで出来ます。
念のために言っておきますが、createdではまだDOMが出来ていないので、idやclassを使ってDOMにアクセスすることは出来ません。
参考サイトはこちら。
まとめ:使っていきながら覚えよう!
ここまで、お疲れ様でした。
一気にライフサイクルフックを覚えるのは結構キツいと思うので、実際に使いながら覚えていきましょう。
自分少し覚えが悪いかも?と思う方もいるかもしれません。
・・・誰だってそうです。(笑)
初めはみんなそうです。知らないのが当たり前です。
なのであせらず1個1個覚えていきましょう。






コメント