Access Vuex State when Defining Vue-Router Routes

I have the following Vuex repository (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') 

I also have the following routes defined for 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 } ] 

I am trying to make sure that if the Vuex store user object has the authenticated property false property, ask the router to redirect the user to the login page.

I have it:

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

The problem is that I don’t know how to access the Vuex store user object from inside the beforeEach function.

I know that I may have the router protection logic inside the components using BeforeRouteEnter , but this will clutter up each component. I want to define it centrally at the router level.

+7
vuejs2 vuex vue-router
source share
3 answers

As suggested here , you can export your store from the file in which it is located and import it into .js routes. It will be something like the following:

You have one 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 

Now in routes.js you can:

 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() } }) 

In main.js you can also import 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') 
+8
source share

I ended up moving the store from main.js and to store / index.js and importing it into the router.js file:

 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
source share

Here is how I would do it.

In App.vue, I will follow a cookie that stores authentication data. (Obviously, I would save the token containing the authentication data as a cookie after authentication).

Now that this cookie is empty, I will direct it to the login / login page. Logging out removes the cookie. Now, if the user hit after logging out, now since the cookie does not exist (which requires the user to be registered), the user will be redirected to the login page.

0
source share

All Articles