从 Vuex 的一个模块改变另一个模块状态

我店里有两个模块。

var store = new Vuex.Store({
modules: {
loading: loading
posts: posts
}
});

在模块 loading中,我有一个属性 saving,它可以设置为 truefalse,还有一个名为 TOGGLE_SAVING的变异函数来设置这个属性。

在模块 posts中,在获取文章之前和之后,我想更改属性 saving。我是通过从 posts模块中的一个操作调用 commit('TOGGLE_SAVING')来完成的。

var getPosts = function (context) {
context.commit(TOGGLE_LOADING);
};

当它试图提交时,我在控制台中得到了如下错误

[vuex] unknown local mutation type: TOGGLE_LOADING, global type: posts/TOGGLE_LOADING

如何使用 commit在另一个模块中变异状态?

63140 次浏览

you can use action to commit mutation which defined in another module,then you will modify state in another module.

like this:

posts: {
actions: {
toggleSavingActions(context) {
// some actions
context.commit("TOGGLE_SAVING"); // defined in loading module
}
}
}

Try it with following parameters as suggested here;

commit('TOGGLE_LOADING', null, { root: true })

If you have namespaced set to true (in Nuxt that's the default when in modules mode), this becomes:

commit('loading/TOGGLE_LOADING', null, { root: true })

You can also import the store, as you normally do in any js file and use it. For example:

// src/state/modules/posts.js


import store from '@/state/store'
...
store.commit('posts/TOGGLE_LOADING')
...

This works pretty well, the only donwside is that can difficult isolate tests or mock-up.


Edition: Recently I have eliminated all code using the technique I mention due the testing problems. Indeed you can always change the state of other modules following the recommended way, as in this example. Very useful if you manage auth and profile in distincts modules.

logout: context => {
return new Promise((resolve) => {
// Clear token in all axios requests
axios.defaults.headers.common['Authorization'] = ''
// Logout from firebase
firebase
.auth()
.signOut()
.then(() => {
// Update state in profile module
context.commit('profile/SET_USER', null, {
root: true
})
resolve()
})
.catch(error => reject(error))
})
}

If you have used namespaced: true in your modules, there are two ways for it:

1- you should add { root: true }:

commit('TOGGLE_LOADING', null, { root: true })

2- define a global action as below (e.g. globalToggleLoading) and call it from any modules you want by dispatch('globalToggleLoading')

globalToggleLoading: {
root: true,
handler({ commit }) {
commit('TOGGLE_LOADING')
}
}

If your modules are not namespaced, you can call any mutations or actions by calling commit, dispatch:

commit('TOGGLE_LOADING')