javascript - 如何正确地链接 Vuex 操作,并正确地改变调用之间的状态?

标签 javascript vue.js vuejs2 vuex

我的应用程序中有一个 Vuex 存储,它定义了 getteractionsmutations。现在,一个操作从 API 请求数据并将接收到的数据提交给操纵状态的突变。这个特定的操作(名为 initConfiguration)加载了一些元数据和配置,这些元数据和配置在执行后续操作之前必须应用于存储。在我的根组件中,我在 mounted lifetime-hook 函数中有一些初始化代码,如下所示:

new Vue({
  el: '#app',
  store,
  render: h => h(App),
  mounted() {
    store.dispatch('initConfiguration').then(() => {
      store.dispatch('loadData')
    })
  }
})

我面临的问题是在调用下一个 Action loadData 之前状态没有改变,因此这个 Action 由于丢失/未初始化的数据而惨败。由于最终可能会调用多个操作,因此我想避免从 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 promise 。为每个 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')    
  }
})

关于javascript - 如何正确地链接 Vuex 操作,并正确地改变调用之间的状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64125155/

相关文章:

javascript - 如何在 Vue JS 应用程序中单击按钮后将其更改为禁用

javascript - Vue.js 将数据从插槽传递到组件实例

vue.js - Vue CLI 4.5.* : "export ' default' (imported as 'Vue' ) was not found in 'vue'

javascript - HTML 内容到 Javascript 代码

javascript - 使用特定 .json 文件的 HTML 表单将 .json 文件加载到 HTML 模板

javascript - function getLargestElement - 如何让它与充满负数的数组一起工作?

javascript - VueJs : Focus on Input using v-el Directive inside v-repeat Directive

laravel - 如何在组件的脚本部分中使用vue-i18n转换功能

javascript - 绑定(bind) session 变量后Vue语法错误

javascript - app.get() 不工作。与 express.js 中 app.use 和 app.get 的区别相关