【问题标题】:How to wait for action to complete before accessing the Vue Store state?如何在访问 Vue Store 状态之前等待操作完成?
【发布时间】:2021-10-19 15:38:41
【问题描述】:

我有Vuejs/Nuxtjs 应用程序,在它被Vuex action 修改后,我需要在其中访问Vuex 存储state。目前,当我尝试运行 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,但都不起作用

任何建议将不胜感激。提前致谢。

【问题讨论】:

  • 您的代码不会等待异步操作完成。尝试在计算属性中添加以下this.formData.returnValue = this.$store.state.modules.DataStore.data
  • 尝试了 Async 和 await 但两者都不起作用 - 你到底尝试了什么?他们应该没有工作,因为他们没有被正确使用。目前你根本没有链接承诺,所以代码显然不会等待它们。

标签: javascript vue.js nuxt.js vuex


【解决方案1】:

你可以在 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)
      })
  }
}

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

import { mapGetters, mapActions } from 'vuex'

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

【讨论】:

    【解决方案2】:

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

    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
       }
    }
    

    【讨论】:

    • 非常感谢您的回复。这按预期工作,但有一个小问题。当我将值分配给我的组件变量this.formData.returnValue = this.$store.state.modules.DataStore.data 时,我收到错误client.js:227 Error: [vuex] do not mutate vuex store state outside mutation。如果我评论这一行,那么一切都会按预期工作。我想知道如何临时将 vuex 状态分配给我的组件变量?
    猜你喜欢
    • 2023-04-04
    • 1970-01-01
    • 2019-03-12
    • 2015-03-31
    • 1970-01-01
    • 2020-10-20
    • 2021-11-26
    • 2021-05-17
    • 2020-02-11
    相关资源
    最近更新 更多