1. ホーム
  2. javascript

[解決済み] Vue-Routerのルート定義時にVuexのステートにアクセスする

2023-07-27 05:59:54

質問

以下のVuexストア(main.js)があります。

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

//init store
const store = new Vuex.Store({
    state: {
        globalError: '',
        user: {
            authenticated: false
        }
     },
     mutations: {
         setGlobalError (state, error) {
             state.globalError = error
         }
     }
})

//init app
const app = new Vue({
    router: Router,
    store,
    template: '<app></app>',
    components: { App }
}).$mount('#app')

また、Vue Router(routes.js)には、以下のルートを定義しています。

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

//define routes
const routes = [
    { path: '/home', name: 'Home', component: Home },
    { path: '/login', name: 'Login', component: Login },
    { path: '/secret', name: 'Secret', component: SecretPage, meta: { requiresLogin: true }
]

をVuexに格納するようにしたいのです。 user オブジェクトを保存し、そのオブジェクトが authenticated プロパティに false に設定すると、ルーターはユーザーをログインページにリダイレクトさせます。

私はこれを持っています。

Router.beforeEach((to, from, next) => {
    if (to.matched.some(record => record.meta.requiresLogin) && ???) {
        // set Vuex state's globalError, then redirect
        next("/Login")
    } else {
        next()
    }
})

問題は、Vuexストアの user オブジェクトの内部から beforeEach 関数の内部で

ルーターガードのロジックをコンポーネントの中に入れるには BeforeRouteEnter を使うこともできますが、それでは各コンポーネントが散らかってしまいます。代わりにルーターレベルで一元的に定義したいのです。

どのように解決するのですか?

提案されているように ここで にあるように、あなたのストアをファイルからエクスポートし、それを routes.js . それは次のようなものになります。

あなたは1つの store.js :

import Vuex from 'vuex'

//init store
const store = new Vuex.Store({
    state: {
        globalError: '',
        user: {
            authenticated: false
        }
     },
     mutations: {
         setGlobalError (state, error) {
             state.globalError = error
         }
     }
})

export default store

現在 routes.js を、持つことができます。

import Vue from 'vue'
import VueRouter from 'vue-router'
import store from ./store.js

Vue.use(VueRouter)

//define routes
const routes = [
    { path: '/home', name: 'Home', component: Home },
    { path: '/login', name: 'Login', component: Login },
    { path: '/secret', name: 'Secret', component: SecretPage, meta: { requiresLogin: true }
]

Router.beforeEach((to, from, next) => {
    if (to.matched.some(record => record.meta.requiresLogin) && ???) {
        // You can use store variable here to access globalError or commit mutation 
        next("/Login")
    } else {
        next()
    }
})

main.js をインポートすることもできます。 store :

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

import store from './store.js'

//init app
const app = new Vue({
    router: Router,
    store,
    template: '<app></app>',
    components: { App }
}).$mount('#app')