これは Vue.js #3 Advent Calendar 2017 – Qiita 21日目の記事です。
Nuxt.js 使ってみたいけど何をつくろうかな〜と思案していたらば、『SEO、OGP……Vue.js製SPAの「困った」を解決できる「Nuxt.js」が便利だ!』という記事でブログを作っていたので、なんだかちょうどよさそうと思い以下を追加してやってみることにしました。
- Contentful から記事を取得する
- トップページに配置するコンポーネント( components/PostPreview.vue )をつくる
- 記事一覧ページと個別記事ページをつくる
-
nuxt generate
で静的ファイルを生成する - GitHub Pages にデプロイ
Nuxt.js ってどんなもんじゃ?という方の参考になれば幸いです
0. とりあえず準備
0-1. Contentful にアカウントを作ったり
Contentful:ドイツのスタートアップ Contentful が開発した、 API に焦点を当てたコンテンツ管理システム(CMS)
以下の記事を参考にして、
以下までを終わらせる。
- アカウント作成
- スペース作成
- Content Delivery API キー作成
- API キーを .contentful.json に設定
0-2. Nuxtのアプリケーションのベースのセットアップをしたり
『SEO、OGP……Vue.js製SPAの「困った」を解決できる「Nuxt.js」が便利だ!』の以下までをちまちまとやって、アプリケーションの大枠を作る。
- 「アプリケーションのセットアップと設定」
- 「ページレイアウトの操作」
- 「ブログのTOPページを作成する」
- 「Aboutページの作成」
0-3. 必要なパッケージを追加インストールしたりすると
npm install --save contentful
npm install --save vue-markdown
npm install --save-dev push-dir
0-4. こんなディレクトリになっているのではないかな...?
-| .nuxt/
-| components/
-| layouts/
-| middleware/(今回は使わない)
-| node_modules/
-| pages/
---| about.vue
---| index.vue
-| plugins/
---| contentful.js
-| static/
-| store/(今回は使わない)
-| .contentful.json
-| .editorconfig
-| .eslintrc.js
-| .gitignore
-| nuxt.config.js
-| package.json
-| README.md
1. Contentful から記事を取得する
pages/index.vue
で非同期データを取得します。
asyncData ({ env }) {
return client.getEntries({
'content_type': env.CTF_BLOG_POST_TYPE_ID,
order: '-fields.publishDate',
'limit': 3
}).then(entries => {
return {
posts: entries.items
}
}).catch(console.error)
}
へ〜、 Nuxt.js には asyncData メソッドっていうのがあるのね。
https://ja.nuxtjs.org/guide/async-data
2. トップページに配置するコンポーネント(components/PostPreview.vue)をつくる
pages/index.vue
で取得した非同期データをコンポーネントに渡します。
<PostPreview :posts="posts"></PostPreview>
export default {
props: ['posts']
}
あ、 asyncData メソッドはページコンポーネントだけで、普通(?)のコンポーネントは持たないのね...。
https://ja.nuxtjs.org/faq/async-data-components/
3. 記事一覧ページと個別記事ページをつくる
Nuxt.js は pages/
ディレクトリ内の Vue ファイルの木構造に沿って、自動的に vue-router の設定を生成してくれます。
記事一覧ページのURLは https://xxxxxxx/posts/
としたいので、 pages/
配下に posts/
ディレクトリを切り、インデックスのページコンポーネントをつくります。
個別記事ページはContentfulから取得したslugで動的にルーティングしたいので、 アンダーバーをつけたページコンポーネント _slug.vue
をつくります。
-| pages/
---| posts/
-----| index.vue // 記事一覧ページ
-----| _slug.vue // 個別記事ページ
---| about.vue
---| index.vue
routes: [
{
path: "/",
component: _5512af1c,
name: "index"
},
{
path: "/posts",
component: _4aea9340,
name: "posts"
},
{
path: "/about",
component: _355ad457,
name: "about"
},
{
path: "/posts/:slug",
component: _4e57d5d0,
name: "posts-slug"
}
]
各ページコンポーネントで、非同期データを取得、取得データの表示などをなんやかやします。
個別記事ページへのリンクはなんとなく名前付きルートにしました。
<nuxt-link :to="{ name: 'posts-slug', params: { slug: post.fields.slug }}" class="card-footer-item">
Read More
</nuxt-link>
https://ja.nuxtjs.org/api/components-nuxt-link
https://router.vuejs.org/ja/api/router-link.html
4. nuxt generate
で静的ファイルを生成する
何もしないと nuxt generate
で生成されるのはルート/
だけです。
そのため、 vue-router で path: "/posts/:slug"
と動的に定義されているルーティングを、 generate プロパティの routes にも設定します。
generate: {
routes () {
return client.getEntries({
'content_type': config.CTF_BLOG_POST_TYPE_ID
}).then((entries) => {
return [...entries.items.map(entry => `posts/${entry.fields.slug}`)]
})
}
},
動的なパラメータのときは Promise を返す関数。
https://ja.nuxtjs.org/api/configuration-generate
5. GitHub Pagesにデプロイ
デプロイ用の scripts を追加しましょう。
"scripts": {
"dev": "nuxt",
"build": "nuxt build",
"start": "nuxt start",
"generate": "nuxt generate",
"deploy": "push-dir --dir=dist --branch=gh-pages --cleanup" //これ
},
GitHub Pages へデプロイするには? https://ja.nuxtjs.org/faq/github-pages
今回はプロジェクトリポジトリにデプロイするので、アプリケーションのベース URL としてリポジトリ名を設定します。
router: {
base: '/nuxt_blog/'
},
この設定をしないと
こうなってほしいのが → https://hisako135.github.io/nuxt_blog/posts
こうなってしまう → https://hisako135.github.io/posts
そして以下コマンドをポチーーーー
npm run generate
npm run deploy
完成
Nuxt.js を初めて使ってみて個人的に「あ、そうなんだ...!」となったことを抜粋しているのでだいぶ端折っていたりあまりエレガントでない部分もありますが、もうちょっとこの子を育てていきたいです2018年。