Join the Stack Overflow Community
Stack Overflow is a community of 6.4 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I'm fairly new to vue.js and trying to build an SPA. Basicly i define all routes from my backend with an alias to my API endpoints. a lot of them using the same component. Data gets fetched with router.beforeEach and vue-resource.

Now when i navigate from a route to another route which share the same template, my router-view doens't get updated.

Here's my code:

 <script>

var data = {
    content: null
}

const site = {
    template:'<div>{{this.title}}</div>',
    data: function () {
      return data.content.body
    }
}

const home = {
    template:'<div>{{this.title}}</div>',
    data: function () {
      return data.content.body
    }
}

const routes = [
            { path: '/api/12.json', component: home, alias: '/' },
            { path: '/api/4.json', component: site, alias: '/projekte' },
            { path: '/api/5.json', component: site, alias: '/projekte/projekt-1' },
            { path: '/api/7.json', component: site, alias: '/projekte/projekt-2' },
            { path: '/api/6.json', component: site, alias: '/projekte/projekt-3' },
            { path: '/api/8.json', component: site, alias: '/agentur' },
            { path: '/api/9.json', component: site, alias: '/lab' },
            { path: '/api/10.json', component: site, alias: '/kontakt' },
        ]

const router = new VueRouter({
    routes
})

router.beforeEach((to, from, next) => {

    Vue.http.get(to.matched[0].path).then((response) => {

        data.content = response;
        console.log(data.content);
        next();

    }, (response) => {

        data.content = {
            'body': {
                'title': 'Error 404'
            }
        };
        next();

    });
})

const app = new Vue({
    router

}).$mount('#app')

</script>
share|improve this question

Your data object is not part of your Vue component. It is defined outside of your Vue app.

Even though your components - home and site returns the data.content.body object, your main data object is not part of Vue's reactivity system. Therefore, the changes in that data object are not tracked.

You can read more about it here: https://vuejs.org/guide/reactivity.html

To ensure that this does not happen, you need to define your data as part of your component itself. And you need to do your http calls as part of mounted hook on the route component, which has access to this.data of the component.

If you need to share data between components (most likely), then you need to use state management using vuex that allows you to have a shared state for the entire Vue app.

You can read more about Vuex here: http://vuex.vuejs.org/en/intro.html

share|improve this answer
    
The documentation of vue-router shows that the global navigation guard can be definded outside link – janthoma Oct 24 at 18:52
    
Yes, you can do it. But it is recommended to contain your code within the app. This will allow your team members to understand better, and you can allocate ownership of each component to a different person, so things are under control. It is more of a practical benefit than technical. – Mani Oct 25 at 1:26

Here's a working example of vue / vue-router / vuex / vue-resource example for API Calls. Thanks at Mani for the hint i needed.

const site = {
    template:'<div>{{ content.title }}</div>',
    computed: {
        content (){
            return store.state.routeContent
        }
    }
}

const home = {
    template:'<div>{{ content.title }}</div>',
    computed: {
        content (){
            return store.state.routeContent
        }
    }
}

const notFound = {
    template: '<div>{{ content.title }}</div>',
    computed: {
        content (){
            return store.state.routeContent
        }
    }
}

const routes = [
    { path: '/api/12.json', component: home, alias: '/' },
    { path: '/api/4.json', component: site, alias: '/projekte' },
    { path: '/api/5.json', component: site, alias: '/projekte/projekt-1' },
    { path: '/api/7.json', component: site, alias: '/projekte/projekt-2' },
    { path: '/api/6.json', component: site, alias: '/projekte/projekt-3' },
    { path: '/api/8.json', component: site, alias: '/agentur' },
    { path: '/api/9.json', component: site, alias: '/lab' },
    { path: '/api/10.json', component: site, alias: '/kontakt' },
    { path: '/*', component: notFound }
]

const store = new Vuex.Store({
    state: {
        routeContent: null
    },
    mutations: {
        routeContent (state, payload) {
            state.routeContent = payload
            document.title = payload.title
        }
    }
})

const router = new VueRouter({
    routes
})

router.beforeEach((to, from, next) => {

    Vue.http.get(to.matched[0].path).then((response) => {
        store.commit('routeContent', response.body)
        next()

    }, (response) => {
        console.log(response);
        errorObject = {
            'title': 'Error 404'
        },
        store.commit('routeContent', errorObject)
        next()

    });
})

const app = new Vue({
    router

}).$mount('#app')
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.