rel1x
rel1x

Reputation: 2441

Can't get access to $root in Vue.js

In my application I have a root page. In this root page I include Navbar component from which I try to get access to variable named currentRoute. My index.js, where I defined currentRoute:

import Vue from 'vue';
import routes from './routes';

var app = new Vue({
    el: '#app',
    data: {
        currentRoute: window.location.pathname,
    },
    computed: {
        ViewComponent () {
            return routes[this.currentRoute] || routes.NotFound;
        }
    },
    render (h) {
        return h(this.ViewComponent)
    }
});

window.addEventListener('popstate', () => {
    app.currentRoute = window.location.pathname;
});

I have home.vue which is default route and where I included a component named Navbar where I try to get access to currentRoute and which looks like:

<template lang="jade">
.navbar
    .row
        .col.text-center
            a.post-outline.navbar--icon(href='/new-post', @click="newPost")
        .col.text-center
            i.email-outline.navbar--icon
        .col.text-center
            i.person-outline.navbar--icon
</template>

<script>
import routes from '../../routes';
export default {
    props: {
        href: String,
        required: true
    },
    computed: {
        isActive () {
            return this.href === this.$root.currentRoute
        }
    },
    methods: {
        newPost: event => {
            event.preventDefault();

            this.$root.currentRoute = this.href;

            window.history.pushState(
              null,
              routes[this.href],
              this.href
            )
        },
    },
}
</script>

My routes.js:

import NotFound from './pages/404.vue';
import Home from './pages/home.vue';
const NewPost = { template: '<p>new post page</p>' }

export default {
    '/': Home,
    '/new-post': NewPost
}

Everything works fine but this.$root is undefined. Why and where is my mistake?

Upvotes: 1

Views: 4788

Answers (2)

thanksd
thanksd

Reputation: 55664

Your method newPost() uses the ES6/2015 arrow function syntax (() => {}), which binds this to the parent context. In your case, the parent context is the module and not the Vue instance, so it doesn't have a reference to the $root.

You need to use to either declare the function normally:

newPost: function(event) { }

Or, you can use the ES6/2015 shorthand:

newPost(event) { }

Upvotes: 1

Krasimir Hristozov
Krasimir Hristozov

Reputation: 111

In vue.js, data is passed from parent to children via props. It's passed by reference so if you change it in the child, it would affect the parent state.

Upvotes: 0

Related Questions