如何在访问 Vue Store 状态之前等待操作完成?

How to wait for action to complete before accessing the Vue Store state?

我有 Vuejs/Nuxtjs 应用程序,我需要在其中访问 Vuex 商店 state,在它被 Vuex action 修改后。目前,当我尝试 运行 actionassignment 时,我得到的是旧状态,而不是 action 之后更新的状态。

如何让代码等待 action 完成然后 运行 下一条语句?以下是我目前的代码: Vuejs 组件:

<template>
  <div>
    <input v-model="formData.value" type="text">
    <button @click="performAction">
      Click Me
    </button>
  </div>
</template>

<script>
export default {
  data () {
    return {
      formData: {
        value: '',
        returnValue: ''
      }
    }
  },
  methods: {
    performAction () {
      // Set the value within the Vuex Store
      this.$store.commit('modules/DataStore/populateData', this.formData.value)

      // Perform the Action
      this.$store.dispatch('modules/DataStore/getData').then(() => {
        console.log("AFTER COMPLETE ACTION")
      })

      // Assign the update value to the variable
      this.formData.returnValue = this.$store.state.modules.DataStore.data
    }
  }
}
</script>

<style>
</style>

Vuex 商店:

export const state = () => ({
  data:''
})

export const mutations = {
  populateData (state, data) {
    state.data = data
  }
}

export const actions = {
    getData ({ commit, state, dispatch }) {
        const headers = { 'Content-Type': 'application/json' }
        this.$axios
            .post('/getUrlData', state.data, { headers })
            .then((response) => {
                console.log("WITHIN RESPONSE")
                commit('populateData',response.data)
            })
            .catch((error) => {
                commit('populateData', 'Unable to obtain data, Error : ' + error)
            })
    }
}

以下是我尝试过但目前没有任何效果的方法:

  1. 我尝试了 .then() 函数。
  2. 我尝试了 Asyncawait,但都不起作用

如有任何建议,我们将不胜感激。提前致谢。

你可以在 vuex 中创建 getter :

export const getters = {
  getData: (state) => state.data,
};
export const actions = {
  async setData ({ commit }, data) {
    const headers = { 'Content-Type': 'application/json' }
    await this.$axios
      .post('/getUrlData', data, { headers })
      .then((response) => {
        console.log("WITHIN RESPONSE")
        commit('populateData',response.data)
      })
      .catch((error) => {
        commit('populateData', 'Unable to obtain data, Error : ' + error)
      })
  }
}

然后在组件中您可以映射 getters 和动作,并调用它们:

import { mapGetters, mapActions } from 'vuex'

computed: {
...mapGetters(['getData']),
},
methods: {
  ...mapActions(['performAction']),
 
  async performAction() {
    await this.setData(this.formData.value)
    this.formData.returnValue = this.getData
  }
}

如果你想在调用方法中链接它,你需要 return 你的承诺。例如:

getData ({ commit, state, dispatch }) {
    const headers = { 'Content-Type': 'application/json' }
    return this.$axios  // now this promise will be returned and you can chain your methods together
        .post('/getUrlData', state.data, { headers })
        .then((response) => {
            console.log("WITHIN RESPONSE")
            commit('populateData',response.data);
            return response.data; //this will allow you do send the data through to the next Then() call if you want to
        })
        .catch((error) => {
            commit('populateData', 'Unable to obtain data, Error : ' + error)
        })
}

使用 async-await IMO 可以更轻松地处理这种情况。变成:

export const actions = {
    async getData ({ commit, state, dispatch }) {
        const headers = { 'Content-Type': 'application/json' }
        const response = await this.$axios.post('/getUrlData', state.data, { headers });
        console.log("WITHIN RESPONSE")
        commit('populateData',response.data);

     }
}

methods: {
async performAction () {
    // Set the value within the Vuex Store
    this.$store.commit('modules/DataStore/populateData', this.formData.value)

     // Perform the Action
     await this.$store.dispatch('modules/DataStore/getData');
     console.log("AFTER COMPLETE ACTION");

    // Assign the update value to the variable
    this.formData.returnValue = this.$store.state.modules.DataStore.data
   }
}