2017-03-05 128 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不存在(需要用户登录),用户将被路由到登录页面。