【Vue.js】Vue CLIで作成したページのtitleとdescriptionを変更する方法を実例で解説|共通の文言を設定する方法(初心者向け・わかりやすい)

vue-js-prograshi(プロぐらし)-kv Vue.js
記事内に広告が含まれていることがあります。

Vue CLIを使ってVue.jsを使ったプロジェクトを作成すると、デフォルトでは、titleはプロジェクト名となっており、全ページ共通です。

descriptionに関しては存在しない状態になっています。

ここではrouterを使って各ページのtitleとdescriptionを設定する手順を実例を交えて解説しています。


(参考)Vue CLIによるWEBページの作成方法

Vue CLIを使ってVueを使ったプロジェクトを作成し、WEBページを表示する方法については下記をご参考ください。

【Vue.js】Vue CLIとは何か?Vueの開発環境を簡単に構築|インストールからブラウザ表示までの手順を実例で解説


作業手順サマリ

titleとdescriptionを設定で編集するのは以下の3つのファイルです。

  1. router > index.js
  2. App.vue
  3. public > index.html

手順は以下の5つのステップになります。

titleとdescriptionを設定する手順
  1. routeにルートにmetaプロパティを追加
  2. App.vueにtitleとdescriptionをセットするメソッドを追加
  3. App.vueのmountedオプションでメソッドを実行
  4. App.vueのwatchオプションで変更を監視
  5. 共通テンプレート(pubulic>index.html)にdescription属性を追加

以下でそれぞれの設定方法を実例を踏まえて解説しています。


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の値を代入しています。

(参考)MDN Document.title


メソッドの補足
  • 引数でrouteインスタンスの入った変数(routeInstance)を渡しています。※変数は次項のmountedオブジェクトで作成します。
  • ルートインスタンス.meta.titleで各ルートに設定されているtitleにアクセスします。
  • titleが設定されていれば、後ろにサイト名をつけた文字列を変数setTitleに格納します。
  • titleタグ(document.title)にsetTitleを代入する。


descriptionをセットするメソッド

descriptionの設定方法は基本的にtitleのメソッドと同じ流れになります。

titleをセットするメソッドとの違い以下になります。

titleとの違い
  • descriptionはmetaタグのname属性なので、querySelecterを指定する。
  • descriptionの値はcontent属性に記述するためsetAttributionで設定する。

設定は以下のようになります。

document.querySelector( "meta[name='description']" ).setAttribute( 'content', 'ディスクリプションの内容')

(参考)MDN document.querySelectorMDN 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オブジェクトの記述します。

mountedとは何か?

mountedはページの読み込みが開始したときに、非常に早い段階で実行される処理です。(コンポーネントやDOMを読み込むよりも早い)


実例

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を実行するという処理になります。

合わせて読みたい

watchの具体的な使い方など詳細については下記をご参考ください。

(参考)【Vue.js】監視プロパティWatchの使い方やメリットを実例で解説 (deepやimmediateオプションとは何か?)


App.vueのscript内のソースコード

上記でApp.vueの編集は完了です(以下手順の2~4の部分)。

titleとdescriptionを設定する手順
  1. routeにルートにmetaプロパティを追加
  2. App.vueにtitleとdescriptionをセットするメソッドを追加
  3. App.vueのmountedオプションでメソッドを実行
  4. App.vueのwatchオプションで変更を監視
  5. 共通テンプレート(pubulic>index.html)にdescription属性を追加


まとめると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つです。

  1. router > index.js
  2. App.vue
  3. 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
タイトルとURLをコピーしました