Vue Metaでページタイトルを動的に切り替える

Task

2019年11月28日 14:00

前回ページごとに動的にタイトルをつけるため、Vue Router のナビゲーションガードを使って画面遷移前にデータの取得するようにしましたが、肝心のタイトル変更がうまくいきませんでした。

しかし、vue-metaを使ったところあっさりと解決しました。

Vue MetaNuxt.jsでも使われている、meta タグの値を変更するライブラリです。

Nuxt.js でなくても Vue を使っていれば使うことができます。

多くのサイトではトップページ以外のページで、[トピック名 - サイトタイトル]や[トピック名 | サイトタイトル]のように、サイトタイトルが必ず末尾または先頭に来るようにしていますが、vue-meta でも同じことが簡単にできます。

yarn(npm)で追加し、Vue.use()で登録します。

yarn add vue-meta
import Vue from "vue";
import VueMeta from "vue-meta";
Vue.use(VueMeta);

Vue の起点となるApp.vueコンポーネントと、投稿を表示するページ/postsコンポーネントと、投稿の詳細ページ/posts/:idコンポーネントがある場合で考えます。

App.vueコンポーネントでは以下のように書きます。

export default {
  metaInfo() {
    return {
      titleTemplate: titleChunk =>
        titleChunk ? `${titleChunk} - サイトタイトル` : "サイトタイトル"
    };
  },
  data() {
    return {
      //
    };
  }
  /** 省略 */
};

titleChunk に値があった場合は末尾にサイトタイトルを付与し、なければサイトタイトルだけを表示します。

こうすることで以降のコンポーネント内で、title が設定されていない場合はサイトタイトルだけが表示されるようになります。

/postsの場合は次のように書きます。

export default {
  metaInfo: {
      title: "投稿一覧"
    }
  }
  /** 省略 */
};

/posts/:idの場合は次のように書きます。

export default {
  metaInfo() {
    return {
      title: this.post.title
    };
  },
  data() {
    return {
      post: {}
    };
  },
  async beforeRouterEnter(to, from, next) {
    const id = to.params.id;
    const res = await axios.get(`/api/posts/${id}`);
    next(vm => (vm.post = res.data));
  }
  /** 省略 */
};

/posts/:idのように動的にデータが変わる場合は、metaInfoを関数として定義します。

metaInfo()はデータが変更されれば反映されるのですが、反映されるまでのラグが気になったので、Vue Router の beforeRouteEnter と組み合わせることで、遷移する頃にはデータが揃っている状態にできます。

API Reference | Vue Meta

p { margin-bottom: 1em; } blockquote p { margin-bottom: initial; } #content ul { padding-left: 40px; } .token.operator { background-color: initial; }

関連記事