【Vue.js】vuex + vue-router でヘッダータイトルを共通化する方法
【Vue.js】vuex + vue-router でヘッダータイトルを共通化する方法:
スマホ向けwebアプリやスマホアプリなんかでよくあるヘッダーのタイトルが切り替わる方法が簡単に実装できるようになります。
以下のようなイメージです。(アイコンが同じなのでわかりにくいかもしれませんがご了承ください)
ホームview表示時
アバウトview表示時
vue ui等で作った場合 routerが変数になっていないので変数に代入する点に注意してください。
初期時
変更後
この状態で afterEachを登録します。
実行してみましょう npmの場合 npm run serve
ページ切り替えでconsoleに「呼ばれたよ!」と表示されましたでしょうか?
先ほど作ったrouterに対して、metaプロパティを追加してあげましょう。
metaプロパティの中は下の例のように任意でいくつでも設定できます。
先ほど作ったrouterで取得できるか確認しましょう。
こちらも成功しましたでしょうか?
正直storeの作り方は人それぞれなので参考程度に見てください。
私の場合はstore.js1つで管理するやり方をとっています。他にmoduleをファイルごとに分けて管理する方法もありますが、個人的に可読性が良く無いなぁと思ったので1つでまとめています。
次にこちらで設定したstateをviewで取得します。
Header.vueなんかを作ってもよかったんですが、今回はわかりやすくApp.vueで作ります。
mapGetters を利用してstateからpageTitleを取得してきています。
これでstoreの値をviewに持ってくることができました。
通常 this.$storeのようにやったとしても vue-routerからstoreにアクセスすることはできません。
しかし、やり方は簡単で Evanさん の言う通り store.jsをimportすればいいだけです。
https://github.com/vuejs/vuex-router-sync/issues/26#issuecomment-254030655
ついでにafterEachの中身も変えてあげましょう。
今回の設計上storeの値を書き換えるのはmutationsなのでそれにアクセスしているactionのchangePageにdispatchしてあげます。
以上で終了です。
実際に動きましたでしょうか?
遷移時の処理はそれぞれに書かないで、router.js一か所でまとめるようにしましょう。
では良いVue.jsライフを
この記事の内容
スマホ向けwebアプリやスマホアプリなんかでよくあるヘッダーのタイトルが切り替わる方法が簡単に実装できるようになります。以下のようなイメージです。(アイコンが同じなのでわかりにくいかもしれませんがご了承ください)
ホームview表示時
アバウトview表示時
実装
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;
router.js
export default router; router.afterEach((to,from) =>{ console.log('呼ばれたよ!') })
ページ切り替えで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.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;
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>
これでstoreの値をviewに持ってくることができました。
vue-routerからstoreにアクセスする。
通常 this.$storeのようにやったとしても vue-routerからstoreにアクセスすることはできません。しかし、やり方は簡単で Evanさん の言う通り store.jsをimportすればいいだけです。
https://github.com/vuejs/vuex-router-sync/issues/26#issuecomment-254030655
ついでに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ライフを
コメント
コメントを投稿