親バカエンジニアのナレッジ帳

webのエンジニアをやっており、日頃の開発で詰まったことや書き残しておきたいことを載せています。

vue.jsでheadの要素を設定する時はvue-headが便利!


SPAでサイトの実装をすべてJavascriptで行う場合、headの要素までもJavascriptで行わなければいけないですよね。
要素を挿入するだけなのでやり方は色々ありますが、やはりライブラリなどを使用して簡単に実装したいところ。
そこで、vue.jsを使用している場合はvue-headが便利です。

使い方は、まずnpmコマンドでインストールします。
※今回の手法はnpmでパッケージ管理をしていることが前提です。

npm install vue-head --save

次に使用するvueコンポーネントそれぞれで以下を記入すれば準備はOKです。

import Vue from 'vue'
import VueHead from 'vue-head'

Vue.use(VueHead)

data関数などと同じインデントでheadを設定し、titleタグ、metaタグ、linkタグ、scriptタグ、styleタグなど必要に応じて値を設定しましょう。設定不要なタグは入力不要です。

data: function () {
  return {
    ...
  }
},
head: {
  title: {
    inner: 'タイトル',
    // innerに入力したものがタイトルになりますが、separatorとcomplementを使用すると「タイトル | 捕捉」のようになります。
    // トップページ以外でよく見ますね。不要な場合は省略可能です。
    separator: '|',
    complement: '捕捉'
  },
  meta: [
    { name: 'description', content: 'descriptionの内容が入ります。' },
    { name: 'viewport', content: 'width=device-width,initial-scale=1.0,user-scalable=no' }
    { charset: 'utf-8' },
    { property: 'og:type', content: 'website' },
    // ... 
  ],
  link: [
    { rel: 'stylesheet', href: '外部cssファイル' },
    { rel: 'shortcut icon', href: 'ファビコン' },
    // ... 
  ],
  script: [
    { type: 'text/javascript', src: '外部jsファイル', async: true},
    // body内に挿入したい場合は「body: true」を入れましょう
    { type: 'text/javascript', src: '外部jsファイル', async: true, body: true},
    // ... 
  ]
},

上記はあくまで予め決まっている固定の値を設定する場合の静的ページでの方法になりますが、TDKなどは実際はAjaxなど非同期通信で取得した値を設定するなど、動的に値を設定することがほとんどかと思います。
このような場合、thisの変数を使うのですが、ただ変数を入れるだけでは上手くいかずfunction関数を使用します。具体的には以下のようになります。

data: function () {
  return {
    title: null, // 別な場所で動的に値を入れる
    description: null,
    keywords: null,
    // ... 
  }
},
head: {
  title: function () {
    return {
      inner: this.title,
      separator: '|',
      complement: '捕捉'
    }
  },
  meta: function () {
    return [
      { property: 'og:title', content: this.title + ' | 捕捉' },
      { property: 'og:description', content: this.description },
      { name: 'description', content: this.description },
      { name: 'keywords', content: this.keywords },
      // ... 
    ]
  },
  script: function () {
    // 以下のように条件次第でscriptの使用有無を分岐することも可能です。
    let script1 = { type: 'text/javascript', inner: '(function) .......)' }
    let script2 = { type: 'text/javascript', inner: '(function) .......)' }
    if (location.host === 'text.com') {
      return [script1, script2]
    } else {
      return [script1]
    }
  }
}

ここで注意点としては、functionを使用してthisで動的に値を設定する場合、Ajax実行後にthisの変数を取得した後などに以下のスクリプトを入力して反映させる必要があります。

this.$emit('updateHead')

ページごとに設定内容は変わりますが、cssやJavascriptの読み込みなど、どのページでも共通の設定内容もあると思います。
そのような場合、共通の設定はApp.vueなど全ページ必ず通る箇所に記入し、個別の設定のみ各コンポーネントに記入すると良いでしょう。

App.vue

head: {
  meta: function () {
    return [
      { property: 'og:title', content: this.title + ' | 捕捉' },
      { property: 'og:description', content: this.description },
      { name: 'description', content: this.description },
      { name: 'keywords', content: this.keywords },
      // ... 
    ]
  }
}

Component1.vue(個別のコンポーネント)

head: {
  title: function () {
    return {
      inner: this.title,
      separator: '|',
      complement: '捕捉'
    }
  }
}


基礎から学ぶ Vue.js

基礎から学ぶ Vue.js