【Nuxt.js】動的ルーティングについて
はじめに
動的ルーティングについてここらで整理をと思い、めも。
動的ルーティングの概要
まず、動的ルーティングとは何か。 以下公式より抜粋。
パラメータを使って動的なルーティングを定義するには .vue ファイル名またはディレクトリ名に アンダースコアのプレフィックス を付ける必要があります。
例えば
pages users _id.vue
_id.vue
が動的ルーティング。
users/1
でアクセスすれば、1のユーザーのページが表示される。
つまり動的に、1のユーザーのページを生成している。
各モードと動的ルーティング
Nuxt.jsには、SSR、SPA、静的の3つのモードが用意されている。
それぞれの動的ルーティングの動きをまとめると以下のような感じかと思う。
SSR -> ⭕️
SPA -> ❌
静的 -> ⭕️
SSR
SSRは、サーバーが動的なルーティングに対しHTMLを作成するため問題なく動く。
SPA
SPAの場合、表示は可能だが、そのページでリロードをすると404となる。 理由としては、そのURLに該当するHTMLファイルがサーバー上になく、参照できないため。 全てブラウザ上で、動的にページを生成しているSPAでは、表示はできても参照はできない。
▽表示はできても
▽リロードするとこうなる
静的
静的はそのままでは、動的ルーティングができません。 少し設定が必要になります。
公式より以下抜粋
generate コマンド(yarn generate)では 動的なルーティング は無視されます。Nuxt はこれらのルートが何であるのか知らないので、生成することができません。
そこで、Nuxtは以下のように解決策を提示しています
動的なパラメーターを用いたルートを生成させたい場合は、動的なルーティングの配列をセットする必要があります。 nuxt.config.js 内に /users/:id のルーティングを追加します:
export default { generate: { routes: [ '/users/1', '/users/2', '/users/3' ] } }
また、 動的なパラメータが必要となった場合は、routesに対して ページのルーティングを返すようにAPIのfetchを行います。 もっとも効率的な方法として、payloadを使用することが勧められています。
上記の例では、サーバーから user.id を利用してルーティングを生成しますが、必要なデータ以外を破棄しています。通常、そのような場合は /users/id.vue の内部から再度データを取得する必要があります。再度取得することは可能ですが、そうした場合は generate.interval オプションに 100 などの値を設定して、サーバーへとコールが溢れないようにする必要があります。このような実装は生成時間の増加へとつながるため、 user オブジェクト自体を、 id.vue のコンテキストに渡すことが望ましいでしょう。上記のコードを、以下のように変更することで、実現することができます :
import axios from 'axios' export default { generate: { routes () { return axios.get('https://my-api/users') .then((res) => { return res.data.map((user) => { return { route: '/users/' + user.id, payload: user } }) }) } } }
このように、 /users/_id.vue から payload へとアクセスすることが可能です :
async asyncData ({ params, error, payload }) { if (payload) return { user: payload } else return { user: await backend.fetchUser(params.id) } }
( ここら辺は公式を見るのが早い )
まとめ
動的ルーティングの設定・使用可否はモードによって異なるので注意して使用しよう。(雑)