Vue Router (vue-router) はVue.js (Nuxt.js)に標準で組み込まれたルーターで、アプリケーションのページ間遷移で役立っています。
一方、VuexはVue.jsもしくはNuxt.jsのアプリケーション全体から状態(データ)をリアルタイムに参照・更新ができる仕組み(状態管理パターン)であり、こちらもよく使われています。
今回の記事では、Vue Router上でVuexに載せられたデータを参照する方法を確認していきます。
結論
/router/index.jsなどの設定ファイル
store のインポート
import store from '../store'
routerインスタンスでのstore参照例
store.getters.getIsValid でgetter経由でisValidステートを参照している
router.beforeEach((to, from, next) => {
if (to.name == 'some-name') {
if (store.getters.getIsValid === false) {
next({
path: '/not-valid-page',
})
} else {
next()
}
} else {
next();
}
});
実行環境
$ node --version
v16.0.0
$ npm list -g vue
/usr/local/lib
└─┬ @vue/cli@4.5.13
└── vue@2.6.14
※以下の方法はVue3でも同じです。
RouterからStoreデータを参照する
Vuexの設定
ここでは簡単化のため、以下のようなstateがVuexに設定されているとします。
/store/index.js などのvuex設定ファイル
state: {
isChecked: false, // Routerで参照する何らかのデータ
},
getters: {
getIsChecked(state) {
return state.isChecked
},
},
isCheckedのデータを参照したいときは getIsChecked() をコールすればOKということですね。
Vue Routerの設定
次にRouterの設定ファイルを開いて、このgetterを呼び出します。
store のインポートを忘れないようにしましょう。
/router/index.js などのrouter設定ファイル
import store from '../store'
vue-routerを初めて設定したときから次のようにrouterインスタンスが生成されていると思います。
const router = new VueRouter({ ... })
このrouterインスタンスはユーザーがページを遷移するたびに参照されるので、これを活用することで条件(データ・状態)に合わせた柔軟なトリガーを設定することができます。
例えば、グローバル before ガード(router.beforeEach)は、どのページが呼び出される時にも必ず事前に呼ばれるコールバックを登録できます。
これを用いてvuexのstateに応じたページの切り替えをやってみましょう。
const routes = [
{
path: '/before-checked',
name: 'BeforeChecked',
component: () => import('../views/BeforeChecked.vue')
},
{
path: '/after-checked',
name: 'AfterChecked',
component: () => import('../views/AfterChecked.vue')
},
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
router.beforeEach((to, from, next) => {
if (to.name == 'AfterChecked') {
if (store.getters.getIsChecked === false) {
next({
path: '/before-checked',
})
} else {
next()
}
} else {
next();
}
});
/after-checked ページにアクセスしようとすると、store.getters.getIsChecked でstate.isCheckedの状態を受け取り、それがfalseのときには /before-checkedに遷移するという流れになります。
他のページへのリダイレクト(移動)はnext({path: 'xxxx'}) またはシンプルにnext('xxxx')とすればOKです。
next() (引数無し)を呼ぶと(他に何もフックが設定されていなければ)このままアクセスしたページが処理されます。
beforeEach グローバルガードはすべてのページ読み込みの前に呼ばれるので、/after-checkedページ以外のページではnext() を呼び、パスします。
今回参考にしたページ・資料