[英]Vuex state in Vue.js computed returning before initialised
我正在嘗試填充圖表的數據,但首先我必須獲取數據來填充它。 這些數據在我的 vuex state 中,它使用 api 請求來獲取數據。 但是當我返回這個 state 時,它是一個空數組。 如何確保在返回之前設置數據?
我的 vuex state;
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)
}
}
};
看到您的問題,您可以在 Vuex store getter 上設置一個觀察者,並在獲得值后執行您的任務。
將吸氣劑定義為
getters: {
getBoardData: state => state.boardColumnData
}
和 map 你的吸氣劑並創建一個觀察者作為
computed: {
...mapGetters(['getBoardData'])
},
watch: {
getBoardData: {
immediate: true,
handler(to, from) {
if(to) {
//handle your changes
this.populate()
}
}
}
}
如果你在同一個組件中調度了動作,因為動作是異步的,你可以鏈接一個回調並在完成時調用populate()
。
您似乎忘記了實際調度操作以獲取數據。 在你創建的鈎子中試試這個:
created() {
this.$store.dispatch('Dashboard', 'getAllBoardPostData');
this.populate();
}
編輯:
在另一個組件中調度操作是可以的。 在這種情況下,創建的鈎子可能在生命周期中太早而無法等待獲取數據(因為該組件不知道執行調度的那個),並且它只運行一次。 您可以添加一個觀察者來等待計算屬性更改並觸發副作用(填充方法)。
watch: {
boardColumns() {
this.populate()
}
}
或者,如果數據對於渲染組件至關重要,您可以考慮使用數據來確定父組件中的v-if
,如 @Estus Flask 建議的那樣。 根據您的組件在重用和與商店的緊密耦合方面的結構方式,您甚至可以在那時將其作為道具傳遞。
// 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>
這是組件在Vuex store
之前呈現的正常行為。 當計算部分將檢查時, store
中不會有數據初始化。
當您使用XHR
請求獲取store
數據時,可能會發生這種情況。
解決方案是在使用computed
屬性的地方使用v-if
條件。 在您的情況下,您可以檢查
v-if = "boardColumns.length>0"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.