我的应用程序中有一个Vuex
存储,它定义了getters
、actions
和mutations
。现在,一个操作从API请求数据,并将接收到的数据提交给操纵状态的突变。此特定操作(名为initConfiguration
(加载一些元数据和配置,这些元数据和配置必须在执行后续操作之前应用于存储。在我的根组件中,我在mounted
生存期挂钩函数中有一些初始化代码,如下所示:
new Vue({
el: '#app',
store,
render: h => h(App),
mounted() {
store.dispatch('initConfiguration').then(() => {
store.dispatch('loadData')
})
}
})
我面临的问题是,在调用下一个操作loadData
之前,状态没有改变,因此由于数据丢失/未初始化,该操作失败得很惨。由于最终可能会调用几个操作,我希望避免从initConfiguration
操作中直接调用loadData
操作(正如我所了解到的,必须避免通过突变调用操作(。
这是我的商店实现。。。
export default Vuex.Store({
state: {
metadata: {
initialized: false,
config: { }
}
},
mutations: {
setConfiguration(state, config) {
state.metadata.config = config
state.metadata.initialized = true
}
},
actions: {
initConfiguration({commit}) {
axios.get('configuration').then((response) => {
commit('setConfiguration', response.data)
})
},
loadData({commit, state}) {
axios.get(state.metadata.config.tenantDataUrl) // crashes here due to undefined data
.then((response) => { ... });
}
}
})
如何正确地链接操作,并确保状态在两者之间得到更新?
您需要返回您的axios承诺。为每个axios调用添加一个返回,您现有的代码就可以工作了。
你也可以像这个一样重写
new Vue({
el: '#app',
store,
render: h => h(App),
async mounted() {
await store.dispatch('initConfiguration')
await store.dispatch('loadData')
}
})
export default Vuex.Store({
state: {
metadata: {
initialized: false,
config: { }
}
},
mutations: {
setConfiguration(state, config) {
state.metadata.config = config
state.metadata.initialized = true
}
},
actions: {
async initConfiguration({commit}) {
const response = await axios.get('configuration')
commit('setConfiguration', response.data)
},
async loadData({commit, state}) {
const response = await axios.get(state.metadata.config.tenantDataUrl) // crashes here due to undefined data
// do whatever with response, or try/catch
}
}
})
如果您需要在每个步骤更新vue模板,请添加此
new Vue({
el: '#app',
store,
render: h => h(App),
async mounted() {
await store.dispatch('initConfiguration')
await this.$nextTick() // cause vue to run getters and update computeds
await store.dispatch('loadData')
}
})