Nuxt.jsの Full Static Generationとは Nuxt 2.13で導入された
APIレスポンスも合わせてすべて静的化するための機能です。
今回はnpm packageのjson-serverをつかってモックapiを作成して、
APIの値を取得して静的書き出しをするところまでやってみます。
(Nuxt @ v2.14.9
で試しています)
API側の準備
jsonを用意
{
"news": [
{
"id": "title_001",
"body": "Hello World"
},
{
"id": "title_002",
"body": "おはようございます"
},
{
"id": "title_003",
"body": "こんにちは"
},
{
"id": "title_004",
"body": "おやすみ"
}
]
}
コマンドの追加
package.json に
npm run api_server
というコマンドを追加します。
"scripts": {
"dev": "nuxt",
"build": "nuxt build",
"start": "nuxt start",
"generate": "nuxt generate",
"api_server" : "node_modules/.bin/json-server --watch db.json --port 3333"
}
Nuxtの準備
nuxt.config.jsの設定
はじめにnuxt.config.jsを
generateモードに設定するためにtargetをstaticにします。
target :"static",
今回のFile構成
-| pages/
---| index.vue
---| news/
-----| _slug.vue
Nuxt v2.13から generate時に内部的にクローリング処理が行われ、
リンク先を自動的に検出してページ生成を行われるようになりました。
たとえばnews/index.vueを作成して
<template>
<div class="container">
<ul>
<li v-for="item in news">
<nuxt-link :to="`/news/${item.id}`">
{{item.body}}
</nuxt-link>
</li>
</ul>
</div>
</template>
<script>
export default {
async asyncData ({ params}) {
return axios.get('http://localhost:3333/news').then((res) => {
return {news : res.data}
}).catch((error) => {
return { error: error }
})
}
}
</script>
このようなファイルを用意してnpm run generate
をたたくと
APIから取得したデータと<nuxt-link>
から動的に静的ファイルが生成されます。
(Nuxt v2.13以降)
今回はリンクされていないページを想定し
_slug.vueにAPIにあるidの値を元に動的にファイルを生成させることにします。
nuxt.config.jsにAPIを取得するコードを追加
generate: {
routes () {
return axios.get('http://localhost:3333/news')
.then((res) => {
return res.data.map((news) => {
return {
route: '/news/' + news.id,
payload: news
}
})
})
}
}
generate routesで使われるのがAPIのレスポンスデータのnews.idを使ってのものだけだと
_sulg.vue側で都度取得することになってしまい生成時間の増加につながってしまうらしく、
そういう場合はpayloadを設定して(今回でいうとAPIのデータ "id","body"をpaylodで渡せる)、動的ルーティング生成の高速化をおこなうようです。
_sulg.vue側のコード
動的に表示する_sulg.vueは下記の様に設定します。
<template>
<div class="container">
<div>
<p>title : {{id}}</p>
<p>content : {{body}}</p>
</div>
</div>
</template>
<script>
import axios from "axios";
export default {
data () {
return {
id:"",
body:""
}
},
async asyncData ({ params, error, payload }) {
if (payload) {
return {
id: payload.id,
body: payload.body,
}
} else {
return axios.get('http://localhost:3333/news').then((res) => {
return res.data.find((post) => post.id === params.slug);
}).catch((error) => {
return { error: error }
})
}
}
}
</script>
npm run dev
で開発できるように
payloadの条件分岐をわけています。
generate
この状態で
1.json-server を立ち上げ
npm run api_server
2.generateする
npm run generate
APIの情報を取り込みファイルを書き出せました。
-| dist/
---| index.html
---| news/
-----| title_001/
-------| index.html
-----| title_002/
-------| index.html
...略
無事APIレスポンスを取り込んで書き出すことができました。
今回はAPIの部分をjson-serverを使ったモックで済ませましたが本来 strapi+nuxt.jsでアドベントカレンダーを作ろうのようにHeadless CMSからのAPIを取得から生成を試して見たかったのですが、それはまたどこかで。
FORK Advent Calendar 2020
15日目 前の日の記事のタイトル @yoh_zzzz
17日目 次の日の記事のタイトル @sy12345