VueJs + Vuex + mapActions
VueJs + Vuex + mapActions
在文档中写道,除了通过操作调用的突变之外,状态是不可变的……好的。
我在我的组件中使用 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:我在商店中使用模块
谢谢
每个 Vuex action returns a Promise
.
Vuexwraps the results of the action functions into Promise
s。所以 changeColor
动作在:
actions: {
changeColor({ commit }, newColor) {
myAsyncCommand();
}
}
Returns 解析为 undefined
的 Promise
并且 不会等待 完成 myAsyncCommand();
的异步代码(如果它不包含异步代码,则无需等待)。
发生这种情况是因为上面的代码与以下代码相同:
changeColor({ commit }, newColor) {
myAsyncCommand();
return undefined;
}
而当 .dispatch('changeColor', ...)
Vuex 将 return Promise.resolve(undefined)
.
如果您希望 Promise
return 由操作编辑的等待,您应该 return 一个 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>
Update/Per 评论:
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?
如果一个动作只调用一个突变,例如:
actions: {
changeColor({ commit }, newColor) {
commit('changeColor', newColor)
return undefined; // added for clarity
}
}
然后 returned Promise
将仅在 commit()
完成后执行 。
这不会发生,因为 Vuex 管理等待突变(commit
s)。
事情就是这样发生的,因为没有等待。这是因为 Vuex 要求:mutations must be synchronous operations.
由于突变是同步的,上面的return
行只会在(commit('changeColor', newColor)
)之前的行代码之后执行。
注意:如果你的 mutations 有异步代码,你应该让它们同步,因为它违背了 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:我在商店中使用模块
谢谢
每个 Vuex action returns a Promise
.
Vuexwraps the results of the action functions into Promise
s。所以 changeColor
动作在:
actions: {
changeColor({ commit }, newColor) {
myAsyncCommand();
}
}
Returns 解析为 undefined
的 Promise
并且 不会等待 完成 myAsyncCommand();
的异步代码(如果它不包含异步代码,则无需等待)。
发生这种情况是因为上面的代码与以下代码相同:
changeColor({ commit }, newColor) {
myAsyncCommand();
return undefined;
}
而当 .dispatch('changeColor', ...)
Vuex 将 return Promise.resolve(undefined)
.
如果您希望 Promise
return 由操作编辑的等待,您应该 return 一个 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>
Update/Per 评论:
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?
如果一个动作只调用一个突变,例如:
actions: {
changeColor({ commit }, newColor) {
commit('changeColor', newColor)
return undefined; // added for clarity
}
}
然后 returned Promise
将仅在 commit()
完成后执行 。
这不会发生,因为 Vuex 管理等待突变(commit
s)。
事情就是这样发生的,因为没有等待。这是因为 Vuex 要求:mutations must be synchronous operations.
由于突变是同步的,上面的return
行只会在(commit('changeColor', newColor)
)之前的行代码之后执行。
注意:如果你的 mutations 有异步代码,你应该让它们同步,因为它违背了 Vuex 的正常工作方式并且可能会产生各种意外行为。