Vue组件methods中async/await调用dispatch数据赋值异常排查
问题原因
相同逻辑放在不同位置表现不一致,本质是异步等待逻辑缺失,和代码写在mounted还是methods里没有关系:
- 你封装的
loadIncomings方法没有标记async,内部调用this.$store.dispatch时也没有加await,dispatch触发的axios异步请求还没返回、Vuex里的incomings状态还没被mutation更新,代码就已经往下执行,提前把state的初始空值赋值给了draftData,同时提前把loaded设为了true。 - 从控制台输出顺序可以直接验证这个问题:组件内打印的
loadIncomings---、draftData---日志,出现在Vuex mutation打印的---UpdateIncomingsInfo---之前,说明赋值逻辑执行时接口请求根本没完成。 - 之前直接把dispatch写在mounted里能正常运行,是因为当时你给dispatch加了await,等请求完成后才做的赋值操作,不是位置带来的差异。
控制台输出表现:
修复步骤
- 给
loadIncomings方法加上async标记,内部调用dispatch时前置await,确保请求完成、state更新后再执行后续赋值逻辑 - 确认Vuex中对应的
loadIncomingsaction正确返回Promise(即axios请求需要被return,或action内部用await等待请求完成后再提交mutation) - 修正mounted里的语法问题,把方法调用之间的逗号改成分号
修复后的组件代码:
<script> import LineChart from "../LineChart"; export default { components: { LineChart }, data: () => ({ loaded: false, chartData: null, labels:[], datasets:[], draftData:null, }), methods: { async loadIncomings(){ // 新增async标记 this.loaded = false try { let clubId = '5c3c5e12ba86198828baa4a7' let dateFrom = '2021-06-01T00:00:00' let dateTo = '2022-07-02T23:59:59' let groupBy = 'month' // dispatch前加await,等待异步请求执行完成 await this.$store.dispatch('loadIncomings', {clubId, dateFrom, dateTo, groupBy}) console.log('loadIncomings---', this.$store.state.incomings) this.draftData = this.$store.state.incomings console.log('draftData---', this.draftData) this.loaded = true } catch (e) { console.error(e) this.loaded = false // 请求失败时重置loaded状态 } }, calcIncomings() { if (this.loaded){ for (let el of this.draftData ) { console.log(el) } } } }, async mounted () { await this.loadIncomings(); await this.calcIncomings(); }, } </script>
对应的Vuex Action参考写法(必须保证返回Promise,否则await不会生效):
actions: { async loadIncomings({commit}, params) { // 等待接口请求返回后再提交mutation更新状态 const { data } = await axios.get('/your/incomings/api', { params }) commit('UpdateIncomingsInfo', data) return data } }
优化建议
更规范的写法是不要直接在组件里读取store.state赋值,可以:
- 用
mapState将Vuex中的incomings映射为组件计算属性直接使用 - 或者直接接收dispatch的返回值给
draftData赋值,减少对state更新时序的依赖
内容的提问来源于stack exchange,提问作者Spartak Borisov
相关产品推荐
相关产品推荐

