【问题标题】:Can't access root data in VueJS无法在 VueJS 中访问根数据
【发布时间】:2017-08-16 04:07:00
【问题描述】:

这是我在 stackoverflow 上的第一篇文章,如果我做错了什么,请提前道歉。我的问题;

我已经设置了一个 VueJS 项目,我正在尝试从另一个组件获取我放入 App.vue 的数据。为此,我以 this.$root.count 为例,但它返回 undefined。

Main.js:

import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App'

Vue.use(VueRouter);

const router = new VueRouter({
mode: 'history',
routes: [{
    path: '/',
    name: 'home',
    component: function (resolve) {
        require(['./components/Hello.vue'], resolve)
    }
}, {
    path: '/race-pilot',
    name: 'racePilot',
    component: function (resolve) {
        require(['./components/RacePilot.vue'], resolve)
    }
}
});

new Vue({
    el: '#app',
    router,
    template: '<App/>',
    components: { App }
});

App.vue:

<template>
<div>
    <div class="menu" ref="menu">
        <router-link :to="{ name: 'home' }">Home</router-link>
        <router-link :to="{ name: 'racePilot' }">Race Pilot</router-link>
    </div>
    <div id="app">
        <router-view></router-view>
    </div>
</div>
</template>

<style src="./assets/css/app.scss" lang="scss"></style>

<script>
import Hello from './components/Hello'

export default {
    name: 'app',
    components: {
        Hello
    },
    data () {
        return {
            count: '0'
        }
    }
}
</script>

RacePilot.vue:

<template>
<div class="race-pilot">
</div>
</template>

<script>
export default {
    name: 'RacePilot',
    mounted() {
        console.log(this.$root.count);
    }
}
</script>

所以最后一个日志返回未定义。但是,如果我记录 this.$root,我确实得到了对象。有人知道吗?提前致谢!

【问题讨论】:

    标签: javascript object vue.js


    【解决方案1】:

    Vuex 很好,但如果你只是想在基于路由器的应用程序中向所有视图公开一个属性,你可以在路由器视图上设置它。

    <router-view :count="count"></router-view>
    

    那么你的视图组件只需要接受它作为一个道具。

    export default {
        props:["count"],
        name: 'RacePilot',
        mounted() {
            console.log(this.count);
        }
    }
    

    【讨论】:

    • 我唯一的问题;如果我在一个非常深的组件中,三个孩子之外,并且想要更改全局变量计数怎么办?由于 this.$root 似乎不起作用...
    • 几个选项。很多人会告诉你使用 Vuex,但我发现 Vuex 对于小型项目来说太过分了。事件总线将是最简单的。或者你可以发明你自己的类 Vuex 存储,使用全局 mixin 对所有组件都可用。
    • 这是一个超级简单的全局数据存储示例codepen.io/Kradek/pen/XMqvPo?editors=1010
    • @BertEvans 不错的答案,提供异步数据(来自服务器)(如用户数据)的最佳方式是什么?
    • @Sandrooco 您的属性可以是异步数据。当它们发生变化时,孩子们将收到更新后的属性。
    【解决方案2】:

    this.$root 引用顶级 Vue 实例(新 Vue...),不是 App VueComponent。

    这真的很hacky,其他解决方案更可取,但这可以工作:

    new Vue({
        el: '#app',
        router,
        template: '<App/>',
        components: { App },
        methods: {
          getCount() {
            return this.$children[0].count
          }
        },
    });
    

    并在 RacePilot.vue 中使用 getCount():

    export default {
        name: 'RacePilot',
        mounted() {
            console.log(this.$root.getCount());
        }
    }
    

    【讨论】:

      【解决方案3】:

      它应该按原样工作,因为它正在工作here

      但是,管理全局变量(跨组件可用)的更好方法应该由状态机解决。 Vue 有 Vuex 用于此目的,如 here 所述。

      【讨论】:

        【解决方案4】:

        你不应该那样做。

        绝对不要尝试访问其他类似的组件。

        要在组件之间共享数据,您可以使用 props(单向绑定)或 Vuex 来让所有组件通过 store 访问和编辑数据。

        如果您将以这种方式启动 Vue 应用程序,则可以使用全局 $store$router

        new Vue({
            el: '#q-app',
            router,
            store
            render: h => h(require('./App'))
          })
        

        然后你就可以访问 store(用于状态改变或访问状态(不要以这种方式改变状态))-this.$store.state.yourStaneName

        【讨论】:

        • 我确实明白,但是,如果我需要根 (app.vue) 中的全局变量怎么办。例如状态变化或一般数据?
        • 已编辑答案,为您提供更多解释,您可以在应用中用作全局。
        • 啊,谢谢,还没有使用 VueX。我去看看!
        【解决方案5】:

        您正在尝试访问存储在 App.vue 中的数据,但该数据将是组件本地的,无法全局访问。

        App.vue 不是根实例(由$root 引用),而是根实例中的第一个组件,实际上是在main.js 创建的。正是在此创建期间,您需要传递数据,这些数据随后将通过$root 向所有子组件公开。

        这里是main.js的相关部分,相应修改:-

        new Vue({
            el: '#app',
            data: { count: 0 },
            router,
            template: '<App/>',
            components: { App }
        });
        

        提示:要确认App.vue 确实是根实例的第一个孩子,请尝试比较this.$rootthis.$parent 的引用。它应该返回true,这意味着根实例是App.vue 的父实例。

        参考:-

        https://vuejs.org/v2/guide/instance.html
        https://vuejs.org/v2/api/#vm-root
        https://vuejs.org/v2/guide/components-edge-cases.html#Accessing-the-Root-Instance

        【讨论】:

          【解决方案6】:

          您还可以通过将组件直接传递给 Vue 实例来使 App 组件成为实际根,如下所示:

          new Vue(App).$mount('#app')
          

          您可能必须将路由器移至App.vue,但这将确保this.$root 将直接解析为您的App 组件。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-11-04
            • 2019-06-06
            • 1970-01-01
            • 1970-01-01
            • 2017-09-15
            相关资源
            最近更新 更多