はじめに
Nuxtのライフサイクル記事はたくさんありますが、コンポーネント別にまとめてくれている記事がなかったため、自分用に作成しました。よく使うんですが、よく忘れるんですよね、、、。
前提
バージョン
Nuxt.js 2.14.4
補足事項
-
nuxtServerInit
store/index.jsに記述しています。 -
beforeEach/afterEach
pluginsにファイルを作成して、nuxt.config.jsで読み込んでいます。 -
fetch
fetchは、公式推奨のcontextなし(引数なし)と非推奨のcontextあり(引数あり)の2種類があります。その同時実行はできませんが、流れをわかりやすくするために「fetch(有)」と「fetch(無)」という表記で両方記載しています。 -
computed
各コンポーネント内のtemplateで呼び出した場合のタイミングを記載しています。 -
SSR/SPA/SSG(静的)【2020/11/1追加】
各モードは、nuxt.config.jsに以下を記載。
※SSGは下記記載しないと動作が変わるので注意。
SSRモード:ssr: true (旧mode: 'universal')
SPAモード:ssr: false (旧mode: 'spa')
SSGモード:ssr:true, target: 'static
-
$nextTick【2021/4/13追記】
コンポーネントのマウントが完了したときに実行されます。 -
コンポーネント【2021/4/13追記】
コンポーネントは全て同期呼び出しを想定しています。
非同期(<lazy-demo />
や() => import(./components/demo.vue)
)でコンポーネントを呼び出し場合は、順番が変わるのでご注意ください。その他の項目に例を記載しています。
全体の流れ
以下のように分けてライフサイクルをまとめます。
- 初回アクセス時
- SSRモード
- SPAモード
- SSGモード
- データ更新時
- SSR/SPA/SSGモード
- ページ遷移時
- SSR/SPAモード
- SSGモード
初回アクセス時
SSRモード
初回アクセス時にサーバーサイドとクライアントサイドでそれぞれ1回ずつ実行されます。
■サーバーサイド
- plugins【nuxt.config.js】
- beforeEach【plugins:nuxt.config.js】
- afterEach【plugins:nuxt.config.js】
- nuxtServerInit【store】
- middleware【nuxt.config.js】
- middleware【layouts】
- middleware【pages】
- validate【pages】
- asyncData【pages】
- fetch(有)【pages】
- beforeCreate【layouts】
- data【layouts】
- created【layouts】
- fetch(無)【layouts】
- computed【layouts】
- beforeCreate【pages】
- data【pages】
- created【pages】
- fetch(無)【pages】
- computed【pages】
- beforeCreate【component】
- data【component】
- created【component】
- fetch(無)【component】
- computed【component】
■クライアントサイド
- plugin【nuxt.config.js】
- beforeEach【plugin:nuxt.config.js】
- afterEach【plugin:nuxt.config.js】
- beforeCreate【layouts】
- data【layouts】
- created【layouts】
- beforeMount【layouts】
- computed【layouts】
- beforeCreate【pages】
- data【pages】
- created【pages】
- beforeMount【pages】
- computed【pages】
- beforeCreate【components】
- data【components】
- created【components】
- beforeMount【components】
- computed【components】
- mounted【components】
- mounted【pages】
- mounted【layouts】
- $nextTick【components】
- $nextTick【pages】
- $nextTick【layouts】
SPAモード
初回アクセス時にクライアントサイドで1回実行されます。
■クライアントサイド
- plugin【nuxt.config.js】
- beforeEach【plugin:nuxt.config.js】
- afterEach【plugin:nuxt.config.js】
- middleware【nuxt.config.js】
- middleware【layouts】
- middleware【pages】
- validate【pages】
- asyncData【pages】
- fetch(有)【pages】
- beforeCreate【layouts】
- data【layouts】
- created【layouts】
- beforeMount【layouts】
- fetch(無)【layouts】
- computed【layouts】
- beforeCreate【pages】
- data【pages】
- created【pages】
- beforeMount【pages】
- fetch(無)【pages】
- computed【pages】
- beforeCreate【components】
- data【components】
- created【components】
- beforeMount【components】
- fetch(無)【components】
- computed【components】
- mounted【components】
- mounted【pages】
- mounted【layouts】
- $nextTick【components】
- $nextTick【pages】
- $nextTick【layouts】
SSGモード
generate時に、SSRモードのサーバーサイドでのライフサイクルが実行されて静的データが生成されます。その生成されたコードに初回アクセス以下のライフサイクルがクライアントサイドで実行されます。
■クライアントサイド
- plugin【nuxt.config.js】
- beforeEach【plugin:nuxt.config.js】
- afterEach【plugin:nuxt.config.js】
- beforeCreate【layouts】
- data【layouts】
- created【layouts】
- beforeMount【layouts】
- computed【layouts】
- beforeCreate【pages】
- data【pages】
- created【pages】
- beforeMount【pages】
- computed【pages】
- beforeCreate【components】
- data【components】
- created【components】
- beforeMount【components】
- computed【components】
- mounted【components】
- mounted【pages】
- mounted【layouts】
- $nextTick【components】
- $nextTick【pages】
- $nextTick【layouts】
データ更新時
ページ内のデータが変更されるときに実行されます。SSR/SPA/SSGモード、どのモードでも全て同じライフサイクルです。
■クライアントサイド
- beforeUpdate【layouts】
- beforeUpdate【pages】
- beforeUpdate【components】
- updated【components】
- updated【pages】
- updated【layouts】
ページ遷移時
SSRとSPAモードは同じライフサイクルで、SSGだけ若干異なります。違いは、asyncDataとfetchがあるかないかだけです。
※layoutは変更したときのみ
SSR/SPAモード
■クライアントサイド
- beforeEach【plugin:nuxt.config.js】
- middleware【nuxt.config.js】
- middleware【layouts】
- middleware【pages】
- validate【pages】
- asyncData【pages】
- fetch(有)【pages】
- afterEach【plugin:nuxt.config.js】
- beforeDestroy【遷移元layouts】
- beforeDestroy【遷移元pages】
- beforeDestroy【遷移元components】
- destroyed【遷移元components】
- destroyed【遷移元pages】
- destroyed【遷移元layouts】
- beforeCreate【layouts】
- data【layouts】
- created【layouts】
- beforeMount【layouts】
- fetch(無)【layouts】
- computed【layouts】
- beforeCreate【pages】
- data【pages】
- created【pages】
- beforeMount【pages】
- fetch(無)【pages】
- computed【pages】
- beforeCreate【components】
- data【components】
- created【components】
- beforeMount【components】
- fetch(無)【components】
- computed【components】
- mounted【components】
- mounted【pages】
- mounted【layouts】
- $nextTick【components】
- $nextTick【pages】
- $nextTick【layouts】
SSGモード
■クライアントサイド
- beforeEach【plugin:nuxt.config.js】
- middleware【nuxt.config.js】
- middleware【layouts】
- middleware【pages】
- validate【pages】
- afterEach【plugin:nuxt.config.js】
- beforeDestroy【遷移元layouts】
- beforeDestroy【遷移元pages】
- beforeDestroy【遷移元components】
- destroyed【遷移元components】
- destroyed【遷移元pages】
- destroyed【遷移元layouts】
- beforeCreate【layouts】
- beforeCreate【layouts】
- created【layouts】
- beforeMount【layouts】
- computed【layouts】
- beforeCreate【pages】
- beforeCreate【pages】
- created【pages】
- beforeMount【pages】
- computed【pages】
- beforeCreate【components】
- beforeCreate【components】
- created【components】
- beforeMount【components】
- computed【components】
- mounted【components】
- mounted【pages】
- mounted【layouts】
- $nextTick【components】
- $nextTick【pages】
- $nextTick【layouts】
ファイル別の利用可能ライフサイクル
あれ、これってここで記述できるんだっけ?ってことが度々あるので、こちらもまとめました。
layouts
- middleware
- beforeCreate
- data
- created
- fetch(無)
- beforeMount
- computed
- mounted
- $nextTick
- beforeUpdate
- update
- beforeDestroy
- destroy
pages
- middleware
- validate
- asyncData
- fetch(有)
- beforeCreate
- data
- created
- fetch(無)
- beforeMount
- computed
- mounted
- $nextTick
- beforeUpdate
- update
- beforeDestroy
- destroy
component
middrewareが呼び出せないこと以外は、基本的にlayoutsと同じです。
- beforeCreate
- data
- created
- fetch(無)
- beforeMount
- computed
- mounted
- $nextTick
- beforeUpdate
- update
- beforeDestroy
- destroy
その他
今回整理する中で、明確になったことまとめ。
fetchの仕様変更
私の知っているfetchいつの間にか非推奨になっていた、、、
まぁ確かに、asyncDataで事足りてはいましたからね。
2020/9/10時点では、context有fetchだと、asyncDataの次に呼ばれ、なしfetchだと、SSRではcreatedの次、CSRではbeforeMountedの次に呼ばれます。
ですので、context無の場合だと、thisを使ってdataやcomputedにアクセスができるんですよね。どんな場合に利用するのかは、下記の記事がわかりやすくまとめてくれています。
computedの実行されるタイミング
- computedに記載しただけでは実行されない。(template内や関数などで呼ぶ必要がある)
- template内での呼び出しの場合は、beforeMountとmountedの間で実行される。
- ライフサイクルから呼び出しができるのは、beforeCreate以降。
同一レイアウトのページ遷移時はmiddlewareのみ実行
同一レイアウトの場合、ページ遷移のたびに実行されるのはmiddlewareのみで、それ以外はレイアウトが切り替わるまで実行されません。
dataにアクセスできるのはcreated以降
beforeCreateではアクセスできませんでした。地味な発見。
旧静的化モードのライフサイクル(Nuxtのバージョン2.13以前)
基本的にSSRモードでgenerateする形になると思いますので、generate時にSSRのライフサイクルが実行されます。そこで生成されたソースにアクセスする形になりますが、その後(CSRとページ遷移)は全く一緒のライフサイクルになります。(ページ遷移でasyncDataやfetchは呼ばれます。)
beforeEachとafterEachの存在
今回、この2つの存在を初めて知りました。
私は、ページ遷移の共通処理はいつもmiddlewareでやってるんですが、より細かい事をしようと思ったときに活躍してくれそうな予感、、、
pluginsは初回に1回しか呼ばれない
いや、これ当たり前といえば当たり前なことなんですが、改めて顕在化されました。
1回だけ処理したい系は基本ここなんですよね。
例えば、SPAモードでnuxtServerInit的なことをしたい場合も、以下の記事のようにpluginsを使って実装します。
[Nuxt.js]nuxtServerInitがSPAモードでは使えないので代替のアクションを用意する
最新の静的モードではfetchとasyncDataは呼ばれない
Nuxtのv2.13.0から静的サイト生成がバージョンアップしました。
静的サイトでリアルタイムな更新はないにもかかわらず、APIでDBを無駄に取得してしまう問題に結構な方が不満を持っていたようで、この度の更新で、fetchとasyncDataが呼ばれなくなったようです。細々したところが便利になっていますので、また別記事でまとめたいと思います。
$nextTickの実行タイミング【2021/4/13追記】
マウント完了後に実行したい時につかっている$nextTick。なんとなく、全コンポーネントのマウント処理が終わった最後に実行されるものと思っていましたが、基本的にはコンポーネント単位での実行でした。
コンポーネントを非同期呼び出し【2021/4/13追記】
コンポーネントを非同期呼び出しした場合、クライアントサイドの処理順番が変わります。
その他のマウントがすべて完了後($nextTick実行後)に、非同期呼び出しのコンポーネントに記載されているbeforeCreateが初めて実行されます。
サーバーサイドの処理は同期/非同期関係なく同じ順番で実行されます。
例:SSGモード/クライアントサイド/初回アクセス
- plugin【nuxt.config.js】
- beforeEach【plugin:nuxt.config.js】
- afterEach【plugin:nuxt.config.js】
- beforeCreate【layouts】
- created【layouts】
- beforeMount【layouts】
- computed【layouts】
- beforeCreate【pages】
- data【pages】
- created【pages】
- beforeMount【pages】
- computed【pages】
- mounted【pages】
- mounted【layouts】
- $nextTick【pages】
- $nextTick【layouts】
- beforeUpdate【pages】 <= ここでpagesの更新前処理
- beforeCreate【components】<= ここで非同期呼び出ししたコンポーネントの処理
- created【components】
- data【components】
- beforeMount【components】
- computed【components】
- mounted【components】
- updated【pages】<= ここでpagesの更新完了処理
- $nextTick【components】
mixinsで呼び出した場合のライフサイクル【2021/7/14追記】
mixinsで挿入した場合は、基本は呼び出したコンポーネントの各ライフサイクルの先に呼ばれます。dataだけ呼び出しサイクル順が違うので注意が必要です。
例:SSGモード/クライアントサイド/初回アクセス、pagesでmixinsを呼び出している場合
- plugin【nuxt.config.js】
- beforeEach【plugin:nuxt.config.js】
- afterEach【plugin:nuxt.config.js】
- beforeCreate【layouts】
- created【layouts】
- beforeMount【layouts】
- computed【layouts】
- beforeCreate【mixins】
- beforeCreate【pages】
- data【pages】<= dataだけ呼び出し元が先
- data【mixins】
- created【mixins】
- created【pages】
- beforeMount【mixins】
- beforeMount【pages】
- computed【pages】
- mounted【mixins】
- mounted【pages】
- mounted【layouts】
- $nextTick【pages】
- $nextTick【layouts】
おわりに
もし違いがあれば、ご指摘いただけると幸いです。
参考
Nuxt.js(Vue.js)SSRのライフサイクルを完全に理解したい(wip)
Vue.js と Nuxt.js のライフサイクル早引きメモ
Nuxt.jsにおけるサーバーサイドレンダリングの挙動とライフサイクル
Nuxt 2.13で導入されたFull Static Generationを試してみる