首页 文章

VueJs Vuex mapActions

提问于
浏览
2

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

我在我的组件,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 Map ,mapActions ..我不喜欢这样调用 . $ store.dispatch

PS2:我在商店里使用模块

谢谢

1 回答

  • 2

    每个Vuex action returns a Promise .

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

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

    返回 Promise ,解析为 undefinedwill not wait for 完成 myAsyncCommand(); 's asynchronous code (if it doesn' t包含异步代码,然后没有等待的事情) .

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

    changeColor({ commit }, newColor) {
        myAsyncCommand();
        return undefined;
      }
    

    然后 .dispatch('changeColor', ...) Vuex将返回 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"));
        }
      }
    })
    
    <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>
    

    更新/每条评论:

    即使mapAction / dispatch返回一个承诺,我在我的情况下也不得不添加一个等待“变异”结束的承诺 . 我从文档中想到,它是通过mapAction精确管理的 . 这是确切的吗?

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

    actions: {
      changeColor({ commit }, newColor) {
        commit('changeColor', newColor)
        return undefined; // added for clarity
      }
    }
    

    然后返回的 Promise 将仅在 commit() 完成后执行 .

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

    它发生的方式是因为没有等待的事情 . 这是因为Vuex需要:mutations must be synchronous operations .

    由于突变是同步的,因此上述 return 的行只会在之前的行代码( commit('changeColor', newColor) )之后执行 .

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

相关问题