Guillaume Vincent
Guillaume Vincent

Reputation: 14791

How can I inject data get in router.beforeEach in my vuejs component?

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

Answers (2)

Philip Holly
Philip Holly

Reputation: 753

I see 3 issues:

  1. The vue-router documentation shows you can access the vm in next in a component's beforeRouteEnter, not a global beforeEach.

  2. 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.

  3. 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

Evis
Evis

Reputation: 561

I normally separate the files and then import the js file to my page, here is how I implement beforeEach rule:

  1. 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,
    });
    
  2. 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

Related Questions