Javascript Vue.js中的Vuex状态在初始化之前计算返回
我试图填充图表的数据,但首先我必须获取数据来填充它。此数据位于我的vuex状态内,该状态使用api请求获取数据。但是当我返回这个状态时,它是一个空数组。如何确保在返回数据之前设置好数据 我的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
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()
}
}
}
}