Vue.jsでrouteによってヘッダーを出し分けする方法を解説

この記事では、Vue.jsでヘッダー(Navigation bar)を出し分けするもっとも簡単だと思われる方法についてご紹介します。

例えば、会員登録機能のあるWebサービスでは、ログイン前とログイン後で出すべきヘッダーが異なることがよくありますね。

ログイン前は、シンプルなサービスのロゴだけのヘッダーログイン後は、各ページへのリンクや、ログアウト動線が置かれたヘッダーといった感じです。なので、ページのroute(URL)によって、出すべきヘッダーを変えてあげる条件分岐処理を描いてあげないといけません。

VueのrouteファイルとApp.vueに少し手を加えることで3分くらいで実装できるので、順を追って見ていきましょう。

Route定義ファイルのnameを修正

アプリのRouteを定義しているファイルがあると思います。イメージとしては、以下のような感じ。

import Router from "vue-router"
import User from "@/components/User"
import Login from "@/components/Login"
import SignUp from "@/components/SignUp"

Vue.use(Router)

export default new Router({
  mode: "history",
  routes: [{
    path: "/user/:id",
    name: "user",
    component: User
  },
  {
    path: "/login",
    name: "login",
    component: Login
  },
  {
    path: "/signup",
    name: "signup",
    component: SignUp
  }]
})

これらの各Routeのnameの部分をログイン前とログイン後で区別がつくように編集してあげましょう。もともとnameがなければ新規に追加してください。

おそらく、だいたいのケースにおいてログイン前のページの方が少ないはずなので、ログイン前Routeのnameの頭に no_auth とかを付与してあげるとかで良いんじゃないでしょうか?

import Router from "vue-router"
import User from "@/components/User"
import Login from "@/components/Login"
import SignUp from "@/components/SignUp"

Vue.use(Router)

export default new Router({
  mode: "history",
  routes: [{
    path: "/user/:id",
    name: "user",
    component: User
  },
  {
    path: "/login",
    name: "no_auth/login",
    component: Login
  },
  {
    path: "/signup",
    name: "no_auth/signup",
    component: SignUp
  }]
})

ちなみにこれらのnameは、$route.name で取得することができるので、App.vueでrouteが変わるたびにnameを取得、それが no_auth を含んでいるか否かでヘッダーを出し分けするロジックが書けます。

App.vueにv-ifを追加

それでは、App.vueからRouteのnameを取得して、ヘッダー出し分けロジックを追加していくところを見ていきましょう。

<template>
  <div id="app">
    <Navigation/>
    <router-view/>
  </div>
</template>

...
import Navigation from "@/components/Navigation"

export default {
  name: "App",
  components: {
    Navigation
  }
}

おそらくもともとはこんな感じになっているのではないでしょうか?
(なぜかcodeのところにscriptタグ書くとエラーが出て保存できないので、…で代用・・・)

ここの、ヘッダーのcomponentの所に以下のような感じで、v-ifを追記してあげます。

<template>
  <div id="app">
    <Navigation1 v-if="$route.name.indexOf('no_auth') == -1"/>
    <Navigation2 v-if="$route.name.indexOf('no_auth') >= 0"/>
    <router-view/>
  </div>
</template>

...
import Navigation1 from "@/components/Navigation1"
import Navigation2 from "@/components/Navigation2"

export default {
  name: "App",
  components: {
    Navigation1,
    Navigation2
  }
}

このv-ifはRouteが切り替わるたびに実行され、ログイン前であれば、ログイン前用のヘッダー、ログイン後であれば、ログイン後用のヘッダーを表示してくれるようになります。

Vuexを使う方法もあると思いますが、こちらの方がシンプルで、初心者にもとっつきやすいでしょう。

参考情報