Reputation: 173
I am trying to wrap my head around Navigation Guards for vue.js. I tried to follow the example but I think I am falling short in connecting my State (store.js) to my Router (routes.js). In my Login.vue component I try and push to a new route after the loadUser has dispatched to the State and subsequently the isLoggedIn is updated to true. In the vue components I use mapState do I need to do the same thing here in routes.js. Or maybe there is a better way to do this. To give a full picture I am using a vue frontend and laravel backend with Sanctum.
Extract from routes.js
const routes = [
{
path: '/',
component: Login,
name: 'login'
},
{
path: '/dashboard',
component: Dashboard,
name: 'dashboard',
meta: { requiresAuth: true }
},
]
const router = new VueRouter({
mode: 'history',
routes // short for `routes: routes`
});
router.beforeEach((to, from, next) => {
// if (to.matched.some(record => record.meta.requiresAuth)) {
if (to.meta.requiresAuth) {
if (store.state.isLoggedIn) {
next();
} else {
next({
name: 'home'
});
}
} else {
next();
}
});
export default router;
Extract from store.js
export default {
state : {
isLoggedIn: false,
}
}
Extract from Login.vue
methods : {
async login() {
this.loading = true;
this.errors = null;
try {
await axios.get('/sanctum/csrf-cookie');
await axios.post('/login', this.user);
logIn();
this.$store.dispatch('loadUser');
this.$router.push({ name: 'logbook'});
} catch (error) {
this.errors = error.response && error.response.data.errors;
}
this.loading = false;
}
},
Upvotes: 0
Views: 567
Reputation: 1921
If you want to access/change the Vuex in VueRouter, you must to use the command router.app.store.state...
.
For example:
const routes = [
{ path: '/', component: Login, name: 'login' },
{ path: '/dashboard', component: Dashboard, name: 'dashboard', meta: { requiresAuth: true } },
];
const router = new VueRouter({
mode: 'history',
routes,
});
router.beforeEach((to, from, next) => {
if (router.app.$store) {
// Example to access the state
console.log(router.app.$store.state.isLoggedIn);
// Example to exec the mutation
router.app.$store.commit('myMutation', 'myArgs');
// Example to exec the action (ATTENTION IS ASYNC)
router.app.$store.dispatch('myAction', 'myArgs');
}
if (to.meta.requiresAuth) {
// ...
} else {
next();
}
});
export default router;
Attention:
You must load the Vuex first than VueRouter. Because, when the VueRouter load the Vuex need to be ready. You can change this in main.js
:
import Vue from 'vue'
import App from './App.vue'
import store from './store' // FIRST IMPORT
import router from './router' // SECOND IMPORT
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
Other thing, I prefer to control of login in cookies, because the user can open many tabs. It's my opinion, you can to do what you prefer.
Upvotes: 2