環境
- 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] (https://jp.vuejs.org/v2/guide/mixins.html) 。
こういうものってけっこう需要があると思うので、そのうち何らかの形でコアに実装されそうですけど、どうなんでしょう?サーバサイドレンダリングを考慮すると難しいのかなぁ。