Vue + vue-router で動的にページタイトルを変更する方法

  • 8
    いいね
  • 0
    コメント

環境

  • Vue 2.3.x
  • vue-router 2.5.x

ディレクトリ構成

├── app.js
├── components
│   ├── App.vue
│   └── Navbar.vue
├── router
│   └── index.js
├── util
│   └── title.js
└── views
    └── About.vue

設定

ページタイトルを生成するファイルを作成:

util/title.js
export default {
  mounted() {
    let { title } = this.$options
    if (title) {
      title = typeof title === 'function' ? title.call(this) : title
      document.title = `App Name - ${title}`
    }
  }
}

util/title.js をグローバルにミックスイン:

app.js
// ...
import titleMixin from './util/title'
import router from './router/index'

Vue.mixin(titleMixin)

new Vue({
  el: '#app',
  router,
  render: h => h(App)
})

これで OK :)

例えば /about ページだと以下のように設定:

views/About.vue
<template v-once>
  <div>
    <h1>About</h1>
    <p>About page.</p>
  </div>
</template>

<script>
  export default {
    title: 'About'
  }
</script>

これで /about のページタイトルが About - App Name になる。

動的にデータを引っ張ってきて、一緒に貼り付けたい場合などは以下のようにやる:

<script>
  export default {
    title() {
      return this.item.title
    }
  }
</script>

まとめ

この方法は vuejs/vue-hackernews-2.0 で実装されている方法です (シンプルに見せるためにサーバーサイドレンダリングの考慮はしていません) 。

あと、グローバルなミックスインは上記のようなカスタムオプションを処理するようなもののみに使用するのが良さそうです。詳しくは ミックスイン - Vue.js

こういうものってけっこう需要があると思うので、そのうち何らかの形でコアに実装されそうですけど、どうなんでしょう?サーバサイドレンダリングを考慮すると難しいのかなぁ。

参考リンク

ヘッドの管理
vuejs/vue-hackernews-2.0