VueJs + Vuex + mapActions

Bri*_*eau 3 vuex vuejs2

在文档中,除了通过动作调用的突变之外,状态是不可变的......好吧。

我在我的组件中使用 mapGetters、mapActions ...

店铺 :

export default {
  namespaced: true,

  state: {
    color: "violet"
  },
  mutations: {
      changeColor(state, newColor) {
          state.color = newColor
      },
  },
  actions: {
    changeColor({ commit }, newColor) {
      commit('changeColor', newColor)
  }
 }
Run Code Online (Sandbox Code Playgroud)

成分 :

...
methods: {
    ...mapActions({
      setColor: 'store/changeColor',
    }),
    myMethodCallByButton(){
       this.setColor("blue").then(response => {
          console.log("change Color done")
       },err => {
          console.log("change Color error")
       })
    }
...
Run Code Online (Sandbox Code Playgroud)

该方法工作正常,商店已更新,除了我从未收到过 console.log ()。

文档中写道,mapActions 相当于 this.$store.dispatch。

  • 为什么我没有收到消息?
  • 还有其他解决方案吗?

PS:我想保留 mapGetters 地图,mapActions .. 我不喜欢调用 this.$store.dispatch

PS2:我在我的商店中使用模块

谢谢

acd*_*ior 5

每个 Vuex操作都返回一个Promise.

Vuex将动作函数的结果包装到Promises 中。所以changeColor行动在:

actions: {
  changeColor({ commit }, newColor) {
    myAsyncCommand();
  }
}
Run Code Online (Sandbox Code Playgroud)

返回一个Promise解析为undefined并且不会等待完成myAsyncCommand();的异步代码(如果它不包含异步代码,则无需等待)。

发生这种情况是因为上面的代码与以下代码相同:

  changeColor({ commit }, newColor) {
    myAsyncCommand();
    return undefined;
  }
Run Code Online (Sandbox Code Playgroud)

.dispatch('changeColor', ...)Vuex 返回时Promise.resolve(undefined)

如果您希望Promise操作返回的 等待 ,您应该返回一个Promise自己等待的属性。类似的东西:

  changeColor({ commit }, newColor) {
    return new Promise((resolve, reject) => {
      myAsyncCommand().then(resolve);
    });
    // or, simply: return myAsyncCommand();
  }
Run Code Online (Sandbox Code Playgroud)

下面的演示实现有更多细节:

const myStore = {
  namespaced: true,
  state: { color: "violet" },
  mutations: {
      changeColor(state, newColor) {
          state.color = newColor
      }
  },
  actions: {
    changeColor_SIMPLE({ commit }, newColor) {
      commit('changeColor', newColor)
    },
    changeColor_COMPLICATED_NO_PROMISE({ commit }, newColor) {
        setTimeout(() => {
          commit('changeColor', newColor)
        }, 2000)
    },
    changeColor_COMPLICATED_WITH_PROMISE({ commit }, newColor) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          commit('changeColor', newColor)
          resolve();
        }, 2000)
      });
    }
  }
};
const store = new Vuex.Store({
  modules: {
    store: myStore,
  }
});
new Vue({
  store,
  el: '#app',
  methods: {
    ...Vuex.mapActions({
      setColorSimple: 'store/changeColor_SIMPLE',
      setColorComplicatedNoPromise: 'store/changeColor_COMPLICATED_NO_PROMISE',
      setColorComplicatedWithPromise: 'store/changeColor_COMPLICATED_WITH_PROMISE',
    }),
    myMethodCallByButton(){
       this.setColorSimple("blue")
       	.then(response => console.log("SIMPLE done"),err => console.log("SIMPLE err"));
      this.setColorComplicatedNoPromise("blue")
       	.then(response => console.log("NO_PROMISE done"),err => console.log("NO_PROMISE err"));
      this.setColorComplicatedWithPromise("blue")
       	.then(response => console.log("WITH_PROMISE done"),err => console.log("WITH_PROMISE err"));
    }
  }
})
Run Code Online (Sandbox Code Playgroud)
<script src="https://unpkg.com/vue@2.5.16/dist/vue.min.js"></script>
<script src="https://unpkg.com/vuex"></script>

<div id="app">
  <p>color: {{ $store.state.store.color }}</p>
  <button @click="myMethodCallByButton">click me and WAIT for 2s</button>
</div>
Run Code Online (Sandbox Code Playgroud)

更新/每评论:

即使 mapAction/dispatch 返回了一个承诺,在我的情况下,我也有义务添加一个等待“突变”结束的承诺。我认为,从文档中,它是通过 mapAction 精确管理的。准确吗?

如果一个动作只调用一个突变,例如:

actions: {
  changeColor({ commit }, newColor) {
    commit('changeColor', newColor)
    return undefined; // added for clarity
  }
}
Run Code Online (Sandbox Code Playgroud)

然后返回Promise将只执行commit()完成。

这不会发生,因为 Vuex 管理等待突变(commits)。

之所以会这样,是因为无需等待。这是因为 Vuex 要求:突变必须是同步操作

由于突变是同步的,所以return上面的代码行只会在 ( commit('changeColor', newColor))之前的代码行之后执行。

注意:如果你的mutation有异步代码,你应该让它们同步,因为它违背了Vuex的正常工作方式,可能会产生各种意外行为。