Javascript Vue.js中的Vuex状态在初始化之前计算返回

Javascript Vue.js中的Vuex状态在初始化之前计算返回,javascript,vue.js,vuex,Javascript,Vue.js,Vuex,我试图填充图表的数据,但首先我必须获取数据来填充它。此数据位于我的vuex状态内,该状态使用api请求获取数据。但是当我返回这个状态时,它是一个空数组。如何确保在返回数据之前设置好数据 我的vuex州 import axios from 'axios'; const state = { boardPosts: [], boardColumnData: [] }; const actions = { getAllBoardPostData: ({commit}) =&g

我试图填充图表的数据,但首先我必须获取数据来填充它。此数据位于我的vuex状态内,该状态使用api请求获取数据。但是当我返回这个状态时,它是一个空数组。如何确保在返回数据之前设置好数据

我的vuex州

import axios from 'axios';

const state = {
    boardPosts: [],
    boardColumnData: []
};

const actions = {
    getAllBoardPostData: ({commit}) => {
        function getBoardColumns() {
            return axios.get('http://localhost:5000/api/summary-board/columns');
        }

        function getBoardPosts() {
            return axios.get('http://localhost:5000/api/summary-board/posts');
        }

        axios.all([getBoardColumns(), getBoardPosts()])
            .then(axios.spread((columnData, postData) => {
                let rawPosts = postData.data;
                let columns = columnData.data;
                let posts = Array.from({length: columns.length}, ()=> []);

                rawPosts.forEach((post) => {
                    // If column index matches post column index value
                    if(posts[post.column_index]){
                        posts[post.column_index].push(post);
                    }
                });

                columns.forEach((column, index) => {
                    let columnValue = 0;

                    posts[index].forEach((post) => {
                        columnValue += post.annual_value;
                    });

                    column.column_value = columnValue;
                });

                commit('setBoardColumns', columns);
                commit('setBoardPosts', posts);
            }))
            .catch(error => console.log(error));
    }
};

const mutations = {
    setBoardPosts: (state, payload) => {
        state.boardPosts = payload;
    },
    setBoardColumns: (state, payload) => {
        state.boardColumnData = payload;
    }
};

export default {
    state,
    actions,
    mutations
};
在我的vue文件中

export default {
    name: "Doughnut",
    computed: {
        boardColumns() {
            return this.$store.state.Dashboard.boardColumnData;
        }
    },
    created() {
        this.populate();
    },
    methods: {
        populate() {
            console.log(this.boardColumns) 
        }
    }
};

您似乎忘记了实际调度操作以获取数据。在创建的钩子中尝试以下操作:

created() {
  this.$store.dispatch('Dashboard', 'getAllBoardPostData');
  this.populate();
}
编辑:

在另一个组件中分派操作是可以的。在这种情况下,创建的钩子在生命周期中可能太早,无法等待数据被提取(因为该组件不知道执行分派的钩子),并且它只运行一次。您可以添加一个观察程序,以等待computed属性更改并触发一个副作用(populate方法)

或者,如果数据是渲染组件所必需的,您可以考虑使用数据来确定父组件中的<代码> V-I/COD>。根据组件在重用和与存储紧密耦合方面的结构,您甚至可以将其作为道具传递下去

// Parent component.vue

<template>
  <Doughnut 
    v-if="boardColumns && boardColumns.length"
    :boardColumns="boardColumns"
  />
</template>

<script>
import Doughnut from './Doughnut.vue'

export default {
  components: {
    Doughnut,
  },
  computed: {
    boardColumns() {
      return this.$store.state.Dashboard.boardColumns
    }
  }
}
</script>

// Doughnut.vue

<template>
  <div>
    {{ boardColumns }}
  </div>
</template>

<script>
  export default {
    name: "Doughnut",
    props: {
      boardColumns: {
        type: Object,
        required: true,
      }
    },
    created() {
      this.populate();
    },
    methods: {
      populate() {
        console.log(this.boardColumns) 
      }
    }
};
</script>
//父组件.vue
从“./Doughnut.vue”导入甜甜圈
导出默认值{
组成部分:{
甜甜圈,
},
计算:{
boardColumns(){
返回此。$store.state.Dashboard.boardColumns
}
}
}
//甜甜圈
{{boardColumns}}
导出默认值{
名称:“甜甜圈”,
道具:{
boardColumns:{
类型:对象,
要求:正确,
}
},
创建(){
这个。填充();
},
方法:{
填充(){
console.log(this.boardColumns)
}
}
};

这是组件在
Vuex存储之前呈现的正常行为。当计算部分进行检查时,
存储中不会初始化数据

当您使用
XHR
请求获取
存储
数据时,可能会发生这种情况

解决方案是使用
v-if
条件,其中
computed
属性正在使用。在你的情况下,你可以检查

v-if = "boardColumns.length>0"

看到您的问题,您可以在Vuex store getter上设置观察程序,并在获得值后执行任务

将getter定义为

getters: {
    getBoardData: state => state.boardColumnData
}
映射getter并创建一个watcher作为

computed: {
    ...mapGetters(['getBoardData'])
},
watch: {
    getBoardData: {
        immediate: true,
        handler(to, from) {
            if(to) {
                //handle your changes
                this.populate()
            }
        }
    }
}

如果在同一组件中调度了操作,因为操作是异步的,那么可以链接回调并在完成时调用
populate()

确保在访问计算属性之前初始化状态,或者如果无法在组件中阻止此操作,在实例化组件之前,请确保状态已初始化。@EstusFlask,我该如何做?使用
v-if
或else。取决于你的部件。哦,是的,我明白了。我的问题是页面上的另一个组件会这样做。我可以从同一页面上的两个组件进行分派,也可以将分派放在根vue文件中?如果另一个组件执行此操作,这就足够了。我只是没有在你的例子中看到它!创建的钩子在生命周期中可能太早,无法等待获取数据(因为该组件不知道执行分派的钩子),并且它只运行一次。您可以添加一个监视程序来等待计算属性的更改watch:{boardColumns(){this.populate()}}`如果有数据对组件的呈现至关重要,那么最好按照Estus Flask的描述在父组件中使用v-If,这样只会在返回数据后创建组件。
computed: {
    ...mapGetters(['getBoardData'])
},
watch: {
    getBoardData: {
        immediate: true,
        handler(to, from) {
            if(to) {
                //handle your changes
                this.populate()
            }
        }
    }
}