Search code examples
javascriptvue.jsvuejs2vuexnuxt.js

Importing reusable actions in Vuex


I'm working on a NUXT project and I find myself copying the same actions into multiple store/modules. So I have extracted the actions to a separate file and I now import it into the module. That works great but I occasionally need an additional action that is not boilerplate. How do I import the boilerplate actions and also have a custom action in the module?

Tags module:

    import Vue from "vue";
    import globalActions from "../utils/Actions.js";
    export const state = () => ({ /* removed */ })
    export const actions = globalActions;
    //Need actions to be a bit more flexible to include non-boilerplate actions

I'm not sure it matters but here is utils/Actions.js It is just the standard "export default {}" that would typically be in the module.

      export default {
        all({ commit }, all) {
          all.data.forEach(item => {
            commit("add", item);
          });
        },

        async list({ commit, state, getters, dispatch }) {
           /* flush resets the state */
           commit("flush");
           /*Makes the api call using the repository setup */
           let params = getters.params;
           const results = await this.$repositories[state.type].index(params);
           const ids = results.data.map(item => item.id);
           let page = state.page;
           dispatch("all", results);
           /*Adds a encyclopedia that maps pages to index */
           commit("SET_REFERENCE", { page, ids });
           commit("totalItems", results.meta.total);
        },
     } 

Ideally, I think the module actions would look something like this:

    export const actions = {
      list(){ return globalActions.list } 
      nonBoilerPlateAction({commit})
    }

I am pretty sure I will need to change how I import the globalActions and that my "ideal" actions syntax is wrong but I not sure what I need to adjust.


Solution

  • To merge the imported actions and the custom actions, you can merge the two actions in this manner:

    export const actions = { 
        ...globalActions, 
        nonBoilerPlateAction({commit}) { 
          commit('something') 
        } 
    }
    

    Although the way you are using to re-use your module works fine, I'll recommend using namespacing instead. This way all your created module can be easily re-used without having to import them to any other file. You can have access to other modules from another module easily.