Vue CLIを使ってVue.jsを使ったプロジェクトを作成すると、デフォルトでは、titleはプロジェクト名となっており、全ページ共通です。
descriptionに関しては存在しない状態になっています。
ここではrouterを使って各ページのtitleとdescriptionを設定する手順を実例を交えて解説しています。
(参考)Vue CLIによるWEBページの作成方法
Vue CLIを使ってVueを使ったプロジェクトを作成し、WEBページを表示する方法については下記をご参考ください。
【Vue.js】Vue CLIとは何か?Vueの開発環境を簡単に構築|インストールからブラウザ表示までの手順を実例で解説
作業手順サマリ
titleとdescriptionを設定で編集するのは以下の3つのファイルです。
- router > index.js
- App.vue
- public > index.html
手順は以下の5つのステップになります。
以下でそれぞれの設定方法を実例を踏まえて解説しています。
routeにルートにmetaプロパティを追加
最初に各ルートにmetaプロパティを作って、titleとdescriptionをオブジェクト形式で記述します。
プロパティ名は任意です。ここでは、わかりやすいように、titleは「title」、 descriptionは「desc」とします。
const routes = [
{
path: 'パス',
name: 'ルート名',
component: コンポーネント,
meta: { title: 'ページタイトル', desc: 'ディスクリプションを記述' }
}
]
なお、これらの情報はルートインスタンス($route)に格納されます。
実例
routerは以下のindex.jsにtitleとdescriptionを設定する場合は以下のようになります。
・router > index.js
index.jsに以下のようにmeta部分を記述します。
const routes = [
{
path: '/',
name: 'Home',
component: Home,
meta: { title: 'ページタイトル', desc: 'ディスクリプションを記述' }
}
]
App.vueにtitleとdescriptionをセットするメソッドを追加
共通コンポーネントであるApp.vueファイルに、titleとdescriptionをセットするメソッドを追加します。
上記でrouterにセットしたmetaプロパティへのアクセス方法は以下のようになります。
ルートインスタンス.meta.設定した変数名
※ルートインスタンス$routeという特別な変数でやりとりされます(Vue.jsの仕様です)。これを使うときは、変数に代入して使います。詳細は次項に記載しています。
titleをセットするメソッド
メソッド名「createTitleDesc」(任意)というメソッドを作成します。
export default {
methods : {
createTitleDesc : function(routeInstance){
//titleを設定する処理
if(routeInstance.meta.title){
var setTitle = routeInstance.meta.title + ' | サイト名など(任意)';
document.title = setTitle;
} else {
document.title = 'ルートでtitleがセットされていない場合に表示するテキスト'
}
}
routeInstanceとは何か?
routeInstanceとは$routeを代入した変数です。次項のmountedで作成します。
document.titleとは何か?
document.titleはHTMLの表記で、ページのタイトルになります。
document.title = setTitle
とすることで、ページタイトルに変数setTitleの値を代入しています。
descriptionをセットするメソッド
descriptionの設定方法は基本的にtitleのメソッドと同じ流れになります。
titleをセットするメソッドとの違い以下になります。
設定は以下のようになります。
document.querySelector( "meta[name='description']" ).setAttribute( 'content', 'ディスクリプションの内容')
(参考)MDN document.querySelector 、 MDN element.setAttribute
実例
上記で作成したtitleを設定するメソッド「createTitleDesc」の中に、descriptionを設定する処理も合わせて記述します。
export default {
methods : {
createTitleDesc : function(routeInstance)
//titleを設定する処理
省略
// メタタグのdescription設定処理
if(routeInstance.meta.desc){
var setDesc = routeInstance.meta.desc + ' | 共通表示名';
document.querySelector("meta[name='description']").setAttribute('content', setDesc)
} else {
document.querySelector("meta[name='description']").setAttribute('content', 'ディスクリプションはありません')
}
}
}
}
routeの中のmetaプロパティの値の中にdescが設定されていない場合はelseの処理になります。
setAttributeの第2引数にはdescriptionがない場合に共通で表示したい内容を指定してください。
App.vueのmountedオプションでメソッドを実行
次にVue.appに作成したメソッド「createTitleDesc」を実行する処理を、同一ファイルのmountedオブジェクトの記述します。
実例
methodsの下に、以下のようにmountedを記述します。
export default {
省略
mounted : function(){
var routeInstance = this.$route;
this.createTitleDesc(routeInstance);
}
}
処理の内容は、まず、routeの情報が入ったルートインスタンス($rounte)を変数routeInstanceに代入します。
次に、titleとdescriptionをセットするメソッドcreateTitleDescを実行します。その際引数にrouteInstanceを渡します。
App.vueのwatchオブジェクトで変更を監視
titleやdescriptionに変更があった場合に、変更内容を自動反映するようwatchオブジェクトを追加します。
export default {
省略
watch: {
'$route' (routeInstance) {
this.createTitleDesc(routeInstance);
}
}
}
watchの使い方
watchは以下のように使います。
watch:{
監視するプロパティ名: function(新しい値用の変数, 古い値用の変数){
処理
}
}
すなわち、$routeを監視して、$routeに変更があったら、変更後の値をrouteInstanceという引数に代入し、メソッドcreateTitleDescを実行するという処理になります。
App.vueのscript内のソースコード
上記でApp.vueの編集は完了です(以下手順の2~4の部分)。
まとめるとApp.vueのscirptタグ内の記述は以下のようになります。
<script>
//routerで設定したタイトルとめたタグを反映する
export default {
methods : {
createTitleDesc : function(routeInstance){
//titleを設定する処理
if(routeInstance.meta.title){
var setTitle = routeInstance.meta.title + ' | サイト名など(任意)';
document.title = setTitle;
} else {
document.title = 'ルートでtitleがセットされていない場合に表示するテキスト'
},
// メタタグのdescription設定処理
if(routeInstance.meta.desc){
var setDesc = routeInstance.meta.desc + ' | 共通表示名';
document.querySelector("meta[name='description']").setAttribute('content', setDesc)
} else {
document.querySelector("meta[name='description']").setAttribute('content', 'ディスクリプションはありません')
}
},
mounted : function(){
var routeInstance = this.$route;
this.createTitleDesc(routeInstance);
},
watch: {
'$route' (routeInstance, from) {
this.createTitleDesc(routeInstance);
}
}
}
</script>
共通テンプレートにdescription属性を追加
Vue CLIでプロジェクトを作成した初期状態では、デフォルトのhtmlテンプレートにdescriptionに該当するタグが存在しません。
このため、WEBページの共通のベースとなるhtmlテンプレートの中にdescriptionを設定する必要があります。
publicフォルダの中の「index.html」のheadタグ内に以下のコードを記述します。
<meta name="description">
これで、App.vueに記載したdocument.querySelector("meta[name='description']")
でこの要素を取得できるようになります。
以上で全ての設定が完了です。
お疲れさまでした。
(確認用)各ファイルのソースコード
上記の手順で編集したファイルは以下の3つです。
- router > index.js
- App.vue
- public > index.html
参考として、それぞれのソースコードを記載しておきます。
(1)router > index.js
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
component: Home,
meta: { title: 'ページタイトル', desc: 'ディスクリプションを記述' }
}
]
})
(2) App.vue
<script>
//routerで設定したタイトルとめたタグを反映する
export default {
methods : {
createTitleDesc : function(routeInstance){
//titleを設定する処理
if(routeInstance.meta.title){
var setTitle = routeInstance.meta.title + ' | サイト名など(任意)';
document.title = setTitle;
} else {
document.title = 'ルートでtitleがセットされていない場合に表示するテキスト'
},
// メタタグのdescription設定処理
if(routeInstance.meta.desc){
var setDesc = routeInstance.meta.desc + ' | 共通表示名';
document.querySelector("meta[name='description']").setAttribute('content', setDesc)
} else {
document.querySelector("meta[name='description']").setAttribute('content', 'ディスクリプションはありません')
}
},
mounted : function(){
var routeInstance = this.$route;
this.createTitleDesc(routeInstance);
},
watch: {
'$route' (routeInstance, from) {
this.createTitleDesc(routeInstance);
}
}
}
</script>
(3) public > index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<!-- 以下を追加 -->
<meta name="description">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
以上です。
参考
以下のページを参考にさせていただきました。
- https://www.sky-limit-future.com/entry/vue_title_desc_tag
- https://router.vuejs.org/ja/guide/essentials/navigation.html
- https://router.vuejs.org/ja/guide/advanced/meta.html