Summer Sale! All accounts are 50% off this week.

Lars-Janssen's avatar

Vue.js $root

Hey,

How do I access the main root component in vue.js 2.0.

I used to do it like this $root.user.name but that does not work anymore! Also this.$root.user.name is not working.

0 likes
10 replies
matt_panton's avatar

If you are not using ES2015 arrow functions the value of this will not be the current Vue instance/component, could you provide more code?

Lars-Janssen's avatar

@matt_panton @ejdelmonico I've got one main App.vue instance. Then in my navigation component I'm trying to set the users name in the template:

<template>
{{ this.$root.user.name }}
</template>

But it's not showing up. If I look into vue-devtools I can see that the user has been set on the main vue instance.

So what could be wrong. I must be able to do this.$root.user.name right?

App.vue:

<template>
    <div class="container">
        <navigation></navigation>
        <main>
            <router-view
                    transition
                    transition-mode="out-in">
            </router-view>
        </main>
        <mainfooter>Company</mainfooter>
    </div>
</template>

<script>
    import Auth         from "../Services/Authentication/Auth";
    import Navigation   from './Shared/Navigation.vue';
    import Mainfooter   from './Shared/Footer.vue';
    import Swal         from 'sweetalert';

    export default {
        components: { Navigation, Mainfooter },

        created() {
            this.loadUser();
            Event.$on('userHasFetchedToken', (token) => Auth.setToken(token));
            Event.$on('userHasLoggedIn', (user) => this.userHasLoggedIn(user));
        },

        data() {
            return {
                user: { role: 1 },
                authenticated: false
            }
        },

        methods: {
            userHasLoggedIn(user) {
                this.user = user;
                this.authenticated = true;
            },

            loadUser() {
                let token = localStorage.getItem('jwt-token');
                if (token !== null && token !== 'undefined') {
                    Auth.getUserData()
                        .then((data) => {
                            this.userHasLoggedIn(data.data.user);
                        }, () => {
                            this.user = null;
                            this.authenticated = false;
                            localStorage.removeItem('jwt-token');
                            if (this.$route.auth) this.$route.router.go('/');

                            swal({
                                title: "Uitgelogd",
                                text: 'Uw sessie is verlopen.',
                                type: "error",
                                timer: 2000,
                                showConfirmButton: false
                            });
                        });
                }
            }
        }
    }
</script>

Navigation.vue:

<template>
    <header>
        <strip color="strip__top"></strip>
        <p>{{ this.$root.authenticated }}</p>
        <nav>
            <ul class="navigation">
                <li class="navigation__item">
                    <p>Home</p>
                </li>
                <li class="navigation__item">
                    <p>Uitloggen</p>
                </li>
            </ul>
        </nav>
    </header>
</template>

<script>
    export default {

    }
</script>

router.js:

import Registration from './Components/Authentication/Registration.vue';
import Login        from './Components/Authentication/Login.vue';
import Forum        from './Components/Forum/Forum.vue';
import VueRouter    from 'vue-router'
import Vue          from 'vue'

Vue.use(VueRouter);

export default new VueRouter({
    mode: 'history',
    routes: [

        /**
         * Authentication
         */

        { name: 'login', path: '/', component: Login },
        { name: 'registration', path: '/registreer', component: Registration },

        /**
         * Forum
         */

        { name: 'forum', path: '/forum', component: Forum },
    ]
});

app.js:

import Strip    from './Components/Shared/Strip.vue';
import Bar      from './Components/Shared/Bar.vue';
import App      from './Components/App.vue';
import router   from './router';
import Vue      from 'vue'

/**
 * We'll register all global components here. So we will be able to use it
 * across the entire application.
 */

Vue.component('bar', Bar);
Vue.component('strip', Strip);

/**
 * We'll require a bootstrap file where all important things are being initialized.
 */

require('./bootstrap');

/**
 * We'll bind the vue instance to #app. That's being used in the main
 * index.blade.php file.
 */

const app = new Vue({
    router,
    render: h => h(App)
}).$mount('#app');
ejdelmonico's avatar

I am not sure but it would seem to me that "this" is not the Vue instance. What happens if you use app?

ejdelmonico's avatar

Maybe if you calculated the user.name in a computed property, which caches the value by default, it might be a work around for now.

Lars-Janssen's avatar

@ejdelmonico I really need to get the user object on the main vue instance. If I do {{ this.$parent.authenticated }} I get the expected result. But if I make a component within a component that's not working anymore. Any idea how I get this on the main vue instance?

With vue.js 1.0 it worked like expected.

Lars-Janssen's avatar

@ejdelmonico hmm okay strange. Because I've imported a lot of components on the main instance but they are not accessible (In vue 1.0 this was working).

Thanks for your help though!

mesqueeb's avatar

@lars6 I've had the same errors with Vue2...

I solved it by adding as a computed property:

    vueRoot()
    { 
        return this.$root;
    },

Then you can write in your template: {{ vueRoot.user.name }}

Please or to participate in this conversation.