VueJs + Vuex + mapActions

时间:2018-03-14 14:39:23

标签: vuejs2 vuex

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

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

商店:

export default {
  namespaced: true,

  state: {
    color: "violet"
  },
  mutations: {
      changeColor(state, newColor) {
          state.color = newColor
      },
  },
  actions: {
    changeColor({ commit }, newColor) {
      commit('changeColor', newColor)
  }
 }

组件:

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

该方法工作正常,存储更新,除了我从未收到console.log()。

在文档中写道,mapActions等同于此。$ store.dispatch。

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

PS:我想保留mapGetters地图,mapActions ..我不喜欢这个。$ store.dispatch

PS2:我在商店中使用模块

谢谢

1 个答案:

答案 0 :(得分:2)

每次Vuex 操作都会返回Promise

Vuex wraps the results of the action functions into Promises。所以changeColor行动在:

actions: {
  changeColor({ commit }, newColor) {
    myAsyncCommand();
  }
}

返回解析为Promise的{​​{1}},并且不会等待完成undefined的异步代码(如果它没有&# 39; t包含异步代码,然后就没等了。)

这是因为上面的代码与:

相同
myAsyncCommand();

changeColor({ commit }, newColor) { myAsyncCommand(); return undefined; } Vuex返回.dispatch('changeColor', ...)时。

如果您希望操作返回的Promise.resolve(undefined)等待,您应该返回一个Promise来执行该属性等待您自己。有点像:

Promise

下面的演示实施,详细信息如下:



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

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"));
    }
  }
})




更新/每条评论:

  

即使mapAction / dispatch返回了一个承诺,我在我的情况下也有义务添加一个等待#34;变异结束的承诺。我从文档中想到,它是通过mapAction精确管理的。这是确切的吗?

如果某个动作仅调用突变,例如:

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

然后,返回的actions: { changeColor({ commit }, newColor) { commit('changeColor', newColor) return undefined; // added for clarity } } 只会在Promise完成后执行

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

这种情况就是这样,因为没有时间等待。这是因为Vuex需要:mutations must be synchronous operations

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

注意:如果您的突变具有异步代码,您应该使它们同步,因为它违反了Vuex正常工作的方式,并可能产生各种意外行为。