4
votes

I have a vuex store with several modules, and I want to be able to listen to "global" dispatch or commit calls (aka actions and mutations) from within a module. For example, in an auth module there are actions like login and logout. Whenever those actions are dispatched, I want another module ui to also perform some action, like setting a language based on the logged in user.

I know I can just dispatch the ui actions from within the login and logout actions in the auth module. But I'd rather have it the other way around, so that ui is listening to the events (actions and/or mutations) dispatched in auth. This way I can easily create side effects without changing the "original" vuex module.

Maybe I need to use watches, but some actions don't alter state so I can't always use them. Creating a plugin is also an option, but I don't want to create an extra plugin each time I want to create such a side effect.

So my question; from within a vuex module, how can I listen to actions/mutations dispatched from other modules?

1
Possible duplicate of Vue listen for Vuex commit?Phiter
Maybe you can subscribe from within the modulePhiter
thanks haven't found that one yet, but it suggests using a plugin. And I'm wondering if there is another way to listen to (or subscribe) to the actions in a moduleWessel van der Linden
I think a plugin would solve it for youPhiter
Using it as a plugin is optional. Subscribe API can be registered on the store instance after it has been created. It is not possible to listen from within a module, since modules are compiled into a single store instance.aBiscuit

1 Answers

0
votes

I created a vuex plugin for myself which can will trigger all refresh action in all stores. But you can do anything else where I called the refresh.

Plugin:

const onModuleAValueChange= (store) => {
    store.watch(
        state => state.moduleA.value,
        (val, oldVal) => {
            // Don't do anything on init state
            if (!oldVal) return;

            // This will trigger all refresh actions on all store. But you can add anything here
            // Essentially does: 
            // store.dispatch(`moduleA/refresh`); 
            // store.dispatch(`moduleB/refresh`); 
            // store.dispatch(`moduleC/refresh`);
            for (let state in store.state) {
                const action = `${state}/refresh`;
                // If the store does not have an refresh action ignore
                if (store._actions[action]) store.dispatch(`${state}/refresh`);
            }

            // Additional action 
            store.dispatch(`moduleC/moduleC_Action`);
        }
    );
};

Store core:

export const store = new Vuex.Store({
    modules: {
        moduleA,
        moduleB,
        moduleC
    },
    plugins: [onModuleAValueChange]
});