2017-03-05 160 views
7

我有以下Vuex存儲(main.js):訪問Vuex狀態

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-路由器定義(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() 
    } 
}) 

的問題是我不知道如何從beforeEach函數內部訪問Vuex商店的user對象。

我知道我可以使用BeforeRouteEnter在組件內部使用路由器保護邏輯,但是這會混淆每個組件。我想在路由器層面集中定義它。

回答

7

如建議here,您可以做的是從您所在的文件中導出商店,並將其導入routes.js。這將是類似以下內容:

你有一個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() 
    } 
}) 

爲主。 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') 
+1

謝謝Saurabh,這正是我最終做的。我會選擇你的答案,因爲它比我的更廣泛。 :) –

0

我結束了移動商店出來main.js,進入店內/ index.js,並將其導入的router.js文件:

import store from './store' 

//routes 

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

//guard clause 
Router.beforeEach((to, from, next) => { 
    if (to.matched.some(record => record.meta.requiresLogin) && store.state.user.authenticated == false) { 
     store.commit("setGlobalError", "You need to log in before you can perform this action.") 
     next("/Login") 
    } else { 
     next() 
    } 
}) 
0

這是我怎麼會到它。

在App.vue中,我將保留一個監視器來存儲認證細節。 (很明顯,我會在驗證後將包含身份驗證詳細信息的令牌存儲爲cookie)

現在無論何時此cookie變空,我都會將用戶路由到/ login頁面。註銷將刪除cookie。現在如果用戶在註銷後重新啓動,現在由於cookie不存在(需要用戶登錄),用戶將被路由到登錄頁面。