VueJs + Vuex + mapActions [英] VueJs + Vuex + mapActions

查看:20
本文介绍了VueJs + Vuex + mapActions的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

商店:

出口默认{命名空间:真,状态: {颜色:紫罗兰"},突变:{更改颜色(状态,新颜色){state.color = newColor},},动作:{changeColor({ commit }, newColor) {commit('changeColor', newColor)}}

组件:

<代码>...方法: {...mapActions({setColor: '存储/更改颜色',}),myMethodCallByButton(){this.setColor("blue").then(response => {console.log("更改颜色完成")},错误=>{console.log("更改颜色错误")})}...

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

文档中写到 mapActions 相当于 this.$store.dispatch.

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

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

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

谢谢

解决方案

每个 Vuex action 都会返回一个 Promise.

Vuex 将动作函数的结果包装成

代码>承诺s.所以 changeColor 动作在:

动作:{changeColor({ commit }, newColor) {myAsyncCommand();}}

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

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

 changeColor({ commit }, newColor) {myAsyncCommand();返回未定义;}

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

如果你想让动作返回的 Promise 等待,你应该返回一个 Promise 来等待自己的属性.类似的东西:

 changeColor({ commit }, newColor) {返回新的承诺((解决,拒绝)=> {myAsyncCommand().then(resolve);});//或者,简单地说: return myAsyncCommand();}

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

const myStore = {命名空间:真,状态:{颜色:紫罗兰色"},突变:{更改颜色(状态,新颜色){state.color = newColor}},动作:{changeColor_SIMPLE({ commit }, newColor) {commit('changeColor', newColor)},changeColor_COMPLICATED_NO_PROMISE({ commit }, newColor) {setTimeout(() => {commit('changeColor', newColor)}, 2000)},changeColor_COMPLICATED_WITH_PROMISE({ commit }, newColor) {返回新的承诺((解决,拒绝)=> {setTimeout(() => {commit('changeColor', newColor)解决();}, 2000)});}}};const store = new Vuex.Store({模块:{商店:我的商店,}});新的 Vue({店铺,el: '#app',方法: {...Vuex.mapActions({setColorSimple: 'store/changeColor_SIMPLE',setColorComplicatedNoPromise: 'store/changeColor_COMPLICATED_NO_PROMISE',setColorComplicatedWithPromise: 'store/changeColor_COMPLICATED_WITH_PROMISE',}),myMethodCallByButton(){this.setColorSimple("蓝色").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 src="https://unpkg.com/vuex"></script><div id="应用程序"><p>color: {{ $store.state.store.color }}</p><button @click="myMethodCallByButton">点击我并等待 2 秒</button>

更新/每条评论:

<块引用>

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

如果一个动作只调用了一个mutation,比如:

动作:{changeColor({ commit }, newColor) {commit('changeColor', newColor)返回未定义;//为清晰起见添加}}

那么返回的Promise只会在commit()完成后执行.

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

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

由于mutation是同步的,上面的return行只会在(commit('changeColor', newColor)之前的那行代码之后执行).

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

In the documentation, it is written that the state is immutable apart from the mutations called via the actions ... Ok.

I use in my component, mapGetters, mapActions ...

store :

export default {
  namespaced: true,

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

component :

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

The method works fine, the store is updated, EXCEPT that I never receive the console.log ().

It is written in the documentation that mapActions were equivalent to this.$store.dispatch.

  • Why do not I get the message?
  • Is there another solution ?

PS: I want to keep the mapGetters map, mapActions .. I do not like calling this.$store.dispatch

PS2: I work with modules in my store

Thank you

解决方案

Every Vuex action returns a Promise.

Vuex wraps the results of the action functions into Promises. So the changeColor action in:

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

Returns a Promise that resolves to undefined and that will not wait for the completion myAsyncCommand();'s asynchronous code (if it doesn't contain async code, then there's no waiting to do).

This happens because the code above is the same as:

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

And when .dispatch('changeColor', ...) Vuex will then return Promise.resolve(undefined).

If you want the Promise returned by the action to wait, you should return a Promise that does the propert waiting yourself. Something along the lines of:

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

Demo implementation below with more details:

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>

Update/Per comments:

Even if the mapAction / dispatch returns a promised, I am in my case obliged to add a promise to wait for the end of the "mutation". I thought, from the documentation, that it was precisely managed via the mapAction. Is it exact?

If an action calls a mutation only, such as:

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

Then the returned Promise will only execute after the commit() completes.

That does not happen because Vuex manages waiting of mutations (commits).

It happens that way because there's no waiting to do. This is because Vuex requires: mutations must be synchronous operations.

Since mutations are synchronous, the line of the return above will only execute after the code of the line before (commit('changeColor', newColor)).

Note: If your mutations have asynchronous code, you should make them synchronous, as it goes against how Vuex properly works and may yield all kinds of unexpected behaviors.

这篇关于VueJs + Vuex + mapActions的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆