【问题标题】:How to pass property to component used in main.js from other components in vuejs如何将属性从 vuejs 中的其他组件传递给 main.js 中使用的组件
【发布时间】:2017-08-22 12:16:47
【问题描述】:

基本上我想要一个全局的loadingbar 组件(包含在应用模板中) 这是我的loadingbar 组件

<template>
    <div class="loadingbar" v-if="isLoading">
        Loading ...
    </div>
</template>

<script>
export default {
    name: 'loadingbar',
    props: ['isLoading'],
    data () {
        return {

        }
    }
}
</script>
<style scoped>
</style>

在main.js 中,我将此组件包含为

import LoadingBar from './components/LoadingBar.vue';
new Vue({
    router,
    data () {
        return {
            isLoading: true
        };
    },
    methods: {
    },
    created: function () {
    },
    components: {
        LoadingBar
    },
    template: `
        <div id="app">
            <LoadingBar :isLoading="isLoading"/>
            <router-view></router-view>
        </div>
    `
}).$mount('#app');

我的目标是根据变量isLoading 的值显示加载组件。上面的代码工作正常。但我想使用来自其他组件的 set isLoading 变量(以便决定是否显示 loading 组件)。例如。在帖子组件

<template>
    <div class="post container">

    </div>
</template>

<script>
export default {
    name: 'post',
    data () {
        return {
            posts: []
        }
    },
    methods: {
        fetchPosts: function() {
            // to show loading bar 
            this.isLoading = true;
            this.$http.get(APIURL+'listpost')
                .then(function(response) {
                    // to hide loading bar 
                    this.isLoading = false;
                    console.log("content loaded");
                });
        }
    },
    created: function() {
        this.fetchPosts();
    }
}
</script>
<style scoped>
</style>

我们无法直接从main.js 访问isLoading,所以我决定使用Mixin,所以我将以下代码放入main.js

Vue.mixin({
    data: function () {
        return {
            isLoading: false
        };
    }
});

然而,这允许我从任何其他组件访问isLoading,但我无法修改此变量。任何人都可以帮助我实现这一目标吗?

注意:我知道我可以通过在单个组件中包含 loadingbar 来实现这一点(我试过了,它工作正常,但我不想这样做,因为每个组件都需要 loadingbar 所以我包括在主模板/组件中)

【问题讨论】:

    标签: vuejs2 vue-component vue-router


    【解决方案1】:

    你可以像这样使用Vuex:

    // main.js 
    import Vuex from 'vuex'
    let store = new Vuex.Store({
      state: {
        isLoading: false,
      },
      mutations: {
        SET_IS_LOADING(state, value) {
          state.isLoading = value;
        }
      },
      getters: {
        isLoading(state) {
          return state.isLoading;
        }
      }
    })
    
    import LoadingBar from './components/LoadingBar.vue';
    new Vue({
      router,
      store, // notice you need to add the `store` var here
      components: {
        LoadingBar
      },
      template: `
        <div id="app">
            <LoadingBar :isLoading="$store.getters.isLoading"/>
            <router-view></router-view>
        </div>
      `
    }).$mount('#app');
    
    // script of any child component
    methods: {
      fetchPosts: function() {
        // to show loading bar 
        this.$store.commit('SET_IS_LOADING', true);
        this.$http.get(APIURL+'listpost')
          .then(function(response) {
            // to hide loading bar 
            this.$store.commit('SET_IS_LOADING', false);
            console.log("content loaded");
          });
      }
    },
    

    【讨论】:

    • 我想我应该采用第二种方式,但是为什么我们必须以第二种方式通过store(在线store, // notice you need to add the store` var here`);本例中没有定义
    • 你不用我复制粘贴的时候忘记拿出来。现已编辑
    • 是的,我尝试过同样的方法,它显示了正确的值,但有些不包括loadingbar
    • 此外,如果在 main.js 中尝试相同的操作(在 $http.get 调用之前设置 this.$isLoading = true;,然后在之后设置 this.$isLoading = false;),它会设置正确的值。但再次显示loadingbar,但在通过$http.get 获取数据后不会被隐藏。我认为 Vue 无法观察对象原型
    • 呵呵,我不知道为什么这不起作用,我可以稍后再看看。现在我已经编辑了我的帖子以包含我知道可行的解决方案。
    猜你喜欢
    • 2019-03-22
    • 1970-01-01
    • 2016-04-27
    • 2021-04-15
    • 2019-03-22
    • 1970-01-01
    • 1970-01-01
    • 2017-10-01
    • 2019-04-03
    相关资源
    最近更新 更多