【问题标题】:vue,js vue-router 2 component data doesn't updatevue,js vue-router 2 组件数据不更新
【发布时间】:2017-03-06 14:25:12
【问题描述】:

我对 vue.js 还很陌生,正在尝试构建一个 SPA。基本上我定义了从我的后端到我的 API 端点的所有路由。他们中的很多人使用相同的组件。使用 router.beforeEach 和 vue-resource 获取数据。

现在,当我从一个路由导航到另一个共享相同模板的路由时,我的路由器视图不会更新。

这是我的代码:

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

【问题讨论】:

    标签: javascript vue.js vue-resource vue-router


    【解决方案1】:

    您的 data 对象不是您的 Vue 组件的一部分。它是在您的 Vue 应用程序之外定义的。

    即使您的组件 - homesite 返回 data.content.body 对象,您的主要 data 对象也不是 Vue 反应系统的一部分。因此,不会跟踪 data 对象中的更改。

    您可以在此处阅读更多信息:https://vuejs.org/guide/reactivity.html

    为确保不会发生这种情况,您需要将data 定义为组件本身的一部分。并且您需要将 http 调用作为路由组件上 mounted 挂钩的一部分,该组件可以访问组件的 this.data

    如果您需要在组件之间共享data(很可能),那么您需要使用使用 vuex 的状态管理,它允许您为整个 Vue 应用程序共享状态。

    您可以在此处阅读有关 Vuex 的更多信息:http://vuex.vuejs.org/en/intro.html

    【讨论】:

    • vue-router的文档显示可以在link之外定义全局导航守卫
    • 是的,你可以做到。但建议将您的代码包含在应用程序中。这将使您的团队成员能够更好地理解,并且您可以将每个组件的所有权分配给不同的人,从而使事情得到控制。它比技术更具有实际意义。
    【解决方案2】:

    这是一个用于 API 调用的 vue / vue-router / vuex / vue-resource 示例的工作示例。感谢Mani 提供我需要的提示。

    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')
    

    【讨论】: