LoginSignup
15
17

More than 5 years have passed since last update.

【Vue.js】vuex + vue-router でヘッダータイトルを共通化する方法

Posted at

この記事の内容

スマホ向けwebアプリやスマホアプリなんかでよくあるヘッダーのタイトルが切り替わる方法が簡単に実装できるようになります。

以下のようなイメージです。(アイコンが同じなのでわかりにくいかもしれませんがご了承ください)

ホームview表示時
0001.JPG

アバウトview表示時
0002.JPG

実装

vue-routerでafter フックを登録する

vue ui等で作った場合 routerが変数になっていないので変数に代入する点に注意してください。

初期時

router.js

export default = new Router({
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home,
    },
  // ----省略----
  ]
})

変更後

router.js

const router  = new Router({
 routes: [
    {
      path: '/',
      name: 'home',
      component: Home,
    },
  // ----省略----
  ]
})
export default router;

この状態で afterEachを登録します。

router.js

export default router;

router.afterEach((to,from) =>{
  console.log('呼ばれたよ!')
})

実行してみましょう npmの場合 npm run serve
ページ切り替えでconsoleに「呼ばれたよ!」と表示されましたでしょうか?

routerにmetaプロパティを追加する

先ほど作ったrouterに対して、metaプロパティを追加してあげましょう。
metaプロパティの中は下の例のように任意でいくつでも設定できます。

router.js

const router  = new Router({
 routes: [
    {
      path: '/',
      name: 'home',
      component: Home,
      meta:{
        title:'ほーむ',
        hoge:'ほげほげ',
      },
    },
  // ----省略----
  ]
})
export default router;

先ほど作ったrouterで取得できるか確認しましょう。

router.js

router.afterEach((to,from) =>{
    console.log(to.meta.title);
    console.log(to.meta.hoge);
})

こちらも成功しましたでしょうか?

storeにstateを追加する。

正直storeの作り方は人それぞれなので参考程度に見てください。
私の場合はstore.js1つで管理するやり方をとっています。他にmoduleをファイルごとに分けて管理する方法もありますが、個人的に可読性が良く無いなぁと思ったので1つでまとめています。

store.js
const store = new Vuex.Store({
  modules: {
    common: {
      namespaced: true,
      state: {
        pageTitle: 'Home',
      },
      actions: {
        changePage({ commit }, title) {
          commit('cahgePageTitle', title);
        },
      },
      mutations: {
        cahgePageTitle(state, title) {
          const st = state;
          st.pageTitle = title;
        },
      },
      getters: {
        pageTitle(state) {
          const st = state;
          return st.pageTitle;
        },
      },
    },
// ----以下省略----
  }
})

export default store;

次にこちらで設定したstateをviewで取得します。
Header.vueなんかを作ってもよかったんですが、今回はわかりやすくApp.vueで作ります。

App.vue

    <div id="header">
      {{pageTitle}}
    </div>

<script>
import { mapGetters } from 'vuex';

export default {
  data() {
    return {};
  },
  computed: {
    ...mapGetters({
      pageTitle:'common/pageTitle',
    }),
  },
};
</script>

mapGetters を利用してstateからpageTitleを取得してきています。
これでstoreの値をviewに持ってくることができました。

vue-routerからstoreにアクセスする。

通常 this.$storeのようにやったとしても vue-routerからstoreにアクセスすることはできません。
しかし、やり方は簡単で Evanさん の言う通り store.jsをimportすればいいだけです。

ついでにafterEachの中身も変えてあげましょう。
今回の設計上storeの値を書き換えるのはmutationsなのでそれにアクセスしているactionのchangePageにdispatchしてあげます。

router.js
import store from './store';

// ----省略----

router.afterEach((to,from) =>{
  if (to.meta && to.meta.title) {
    store.dispatch('common/changePage', to.meta.title)
  }
})

以上で終了です。
実際に動きましたでしょうか?

まとめ

遷移時の処理はそれぞれに書かないで、router.js一か所でまとめるようにしましょう。
では良いVue.jsライフを

15
17
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
17