Reputation: 14791
I use router.beforeEach to protect some view. I fetch my user before entering in my vue. I want to use this user in all my authenticated pages. How can I inject data get in router.beforeEach in my vuejs component?
Here my routes definition:
import Vue from 'vue';
import VueRouter from 'vue-router';
import AuthService from './services/AuthService';
import Index from './pages/Index.vue';
Vue.use(VueRouter);
const routes = [
{path: '/', name: 'index', component: Index, meta: {requiresAuth: true}},
...
];
const router = new VueRouter({
routes
});
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
AuthService().getUser(user => {
if (user) {
next(vm => {
vm.user = user
});
} else {
...
}
});
}
...
});
export default router;
here my Index.vue
<template>
<div>
{{user}}
</div>
</template>
<script type="text/ecmascript-6">
export default {
data(){
console.log(this.user);
console.log(this.$route.user);
return {}
},
mounted(){
console.log(this.user);
console.log(this.$route.user);
}
}
</script>
Everything is undefined
I don't want to make a beforeRouteEnter
in my component because it will make a second API call.
Upvotes: 7
Views: 26886
Reputation: 753
I see 3 issues:
The vue-router documentation shows you can access the vm in next
in a component's beforeRouteEnter
, not a global beforeEach
.
In next
, the vm has already been created because you can access its properties, so you wouldn't be able to see this.user
in the data
function. Maybe in the mounted
function, but we don't know if the vm is returned before or after the component is mounted.
You shouldn't set top-level properties on a vm because they will not be reactive: see https://v2.vuejs.org/v2/api/#data and https://v2.vuejs.org/v2/api/#Vue-set .
Perhaps your AuthService
could store the user and your components get the user from there?
Upvotes: 2
Reputation: 561
I normally separate the files and then import the js file to my page, here is how I implement beforeEach rule:
Routes file:
import VueRouter from 'vue-router';
let routes = [
{
path: '/',
component: require('./views/Home')
},
{
path: '/about',
component: require('./views/About'),
}
];
export default new VueRouter({
routes,
});
Vue App file:
import router from './routes';
// Here goes my logic
router.beforeEach((to, from, next) => {
if ( from.name == 'About' ) {
next(false);
} else {
next();
}
});
const app = new Vue({
el: '#app',
router
});
Hope it helps!
Upvotes: 3