Nuxt.jsでh1(ページタイトル)をlayoutsレンダリングする方法

エンジニア向けの記事です。Nuxt.jsでヘッダーやらに入れる文字をページごとに変えたいけど、記述はlayoutsに纏めたいという方向けの記事です。

できること

記事タイトルやら、記事のサムネイルやらをlayoutsで表示することができます

前提

・単一ファイルコンポーネント使ってる
・ブログの記事タイトルとかパンクズとかをlayoutsでレンダリングする
・vuex利用

結論

pagesでlayoutsに表示したいものをstoreに上げて、layoutsでstoreを読み込んで表示します。そのままです。
$emitでやる方法もあるけど、storeの方が楽だしstoreは別ファイルで呼び出す物を定義するためのものなので、storeを使います。

コード

store/index.js
入れ物とストア更新用関数を定義

const INPUT_UPDATE = 'INPUT_UPDATE'
const UPDATE_DISABLED = 'UPDATE_DISABLED'
const RESET_INPUT_DATA = 'RESET_INPUT_DATA'

const initialState = {
 page: {
   title: 'title',
   description: 'タイトル',
   breadcrumb: {
     content: [{ link: '/', label: 'トップ' }]
   }
 }
}

export const state = () => Object.assign({}, initialState)

export const mutations = {
 [INPUT_UPDATE](state, payload) {
   state[payload.path] = payload.obj
 }
}

pages配下
パン屑とタイトル(ページごとに変えたいもの)をstoreに上げる
ページ読み込み前に変えたいので、asyncDataで更新する

<template>
  ...
</template>

<script>
export default {
 layout: 'single',
 async asyncData({ store }) {
   const path = 'page'
   const obj = {
     title: 'ブログタイトル',
     description: 'ブログ記事です'
   }
   store.commit('INPUT_UPDATE', { obj, path })
 }
}
</script>

layouts/single.vue
ここでstoreを呼び出してレンダリング

<template>
 <div>
   <h1>
     {{ page.title }}
   </h1>
   <p>
     {{ page.description }}
   </p>
   <nuxt />
 </div>
</template>

<script>
import { mapState } from 'vuex'

export default {
  computed: mapState({
    page: state => state.page
  })
}
</script>

まとめ

すごいシンプルだけど、結構使える組み方です。
こうすればpages配下はコンテンツ部分だけ貼れば良くなるので、構成がすっきりします。
nuxtでブログを作るのであれば、是非御賞味あれ。

いいなと思ったら応援しよう!