daninthemix
daninthemix

Reputation: 2570

How do I break up my vuex file?

I have a vuex file with a growing mass of mutators, but I'm not sure of the correct way of splitting it out into different files.

Because I have:

const store = new Vuex.Store({ vuex stuff }) and then below that my main Vue app declaration: const app = new Vue({ stuff })

I'm happy working with Vue components and have lots of those already, but this is stuff at the top level of the app and I'm not sure how to break it apart. Any advice appreciated.

Upvotes: 26

Views: 24508

Answers (7)

velly.zhou
velly.zhou

Reputation: 11

For more nested moudles, you can export 'modules' in sub-module.

How to expose moudles in sub module?

import Vuex from 'vuex';
import Vue from 'vue';
import actions from './actions';
import getters from './getters';
import mutations from './mutations';
import moudles from './moudles';

Vue.use(Vuex);

export const store = new Vuex.Store({
  state: {
    someObj: {},
  },
  actions,
  getters,
  mutations,
  moudles,
});
└── src
    ├── assets
    ├── components
    └── store
       └─ modules
          └─ module1
              ├── state.js
              ├── actions.js
              ├── mutations.js
              ├── getters.js
              └── index.js
              ├── modules
                 |____moudleA (state.js.....)
                 |____moudleB (state.js.....)         
                  
         └─ module2
              ├── state.js
              ├── actions.js
              ├── mutations.js
              ├── getters.js
              └── index.js
   └─ index.js

More details pls refer to https://vuex.vuejs.org/guide/modules.html

Upvotes: 0

Non404
Non404

Reputation: 1293

This is another option for splitting your store and have diferent modules, this is already tested.

structure

└── src
    ├── assets
    ├── components
    └── store
       └─ modules
          └─ module1
              ├── state.js
              ├── actions.js
              ├── mutations.js
              ├── getters.js
              └── index.js
         └─ module2
              ├── state.js
              ├── actions.js
              ├── mutations.js
              ├── getters.js
              └── index.js
   └─ index.js

store/index.js


import Vuex from "vuex";
import thisismodule1 from "./modules/module1";
import thisismodule2 from "./modules/module2";

const createStore = () => {
  return new Vuex.Store({
    modules: {
      module1: thisismodule1,
      module2: thisismodule2

    }
  });
};

export default createStore;

store/modules/module1/index.js

import actions from './actions';
import getters from './getters';
import mutations from './mutations';
import state from './state';


export default {
  state,
  actions,
  mutations,
  getters
}

store/modules/module2/index.js

import actions from './actions';
import getters from './getters';
import mutations from './mutations';
import state from './state';


export default {
  state,
  actions,
  mutations,
  getters
}

Tipp: Don't forget to import your store to your main.js

Documentation: https://vuex.vuejs.org/en/modules.html

Upvotes: 32

user7396942
user7396942

Reputation:

i have this structure:

└── store
          └─ module1
              ├── actions.js
              ├── mutations.js
              ├── getters.js
              └── index.js
   index.js 

and you can copy this example code : index.js from module1

    import actions from "./actions";
    import getters from "./getters";
    import mutations from "./mutations";
    
    import { state } from "./state";

    export default {
     state: () => state,
     actions,
     mutations,
     getters,
   };

state:

export let state = {
  themes: [],
};

getters:

const themesList = (state) => {
  return state.themes;
};

actions:

const getThemesList = async ({ commit }) => {
  
  commit(types.GET_THEMES, [values]);
};

mutations:

const GET_THEMES = (state, themes) => {
  state.themes = themes;
};

and in the main index.js in store put this

const createStore = () => {
  return new Vuex.Store({
    modules: {
      module1: module1,
    },
  });
};

export default createStore;

Upvotes: 0

Anouar khaldi
Anouar khaldi

Reputation: 782

You can use this structure with dynamically load store modules.

src
└─ store
   └─ modules
      └─ [module-name].js
      └─ ...
   └─ index.js // <- your store main file

and in index.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

// Load store modules dynamically.
const requireContext = require.context('./modules', false, /.*\.js$/)

const modules = requireContext.keys()
  .map(file =>
    [file.replace(/(^.\/)|(\.js$)/g, ''), requireContext(file)]
  )
  .reduce((modules, [name, module]) => {
    if (module.namespaced === undefined) {
      module.namespaced = true
    }

    return { ...modules, [name]: module }
  }, {})

export default new Vuex.Store({
  modules
})

after that, just put your module [name].js in modules folder, eg:
auth.js:

// state
export const state = {}

// getters
export const getters = {}

// mutations
export const mutations = {}

// actions
export const actions = {}

to access your actions/getters.. You must write:

export default {
  computed: {
    ...mapGetters({
      method_1: '[module-name]/method_1',
      method_2: '[module-name]/method_2',
    }),
    method_with_arg(){
      return this.$store.getters['[module-name]/method_with_arg'](this.n)
    }
  },
...

You can find demo here (laravel-vue-spa) by Cretu Eusebiu.
Thank you.

Upvotes: 0

bjbk
bjbk

Reputation: 408

In addition to @bigsee's fine answer, if using an index.js file to export the module:

└── src
    ├── assets
    ├── components
    └── store
          └─ mymodule
              ├── state.js
              ├── actions.js
              ├── mutations.js
              ├── getters.js
              └── index.js

index.js

import state from './state'
import * as getters from './getters'
import * as mutations from './mutations'
import * as actions from './actions'

export default {

  state,
  getters,
  mutations,
  actions
}

getters.js

const getData = state => state.data

export {
  getData
}

Similar with actions, mutations and state files.

Upvotes: 7

bigsee
bigsee

Reputation: 959

For those who would like to break up the Vuex file without creating a more complex modular application structure, I think it is also possible to simply break the actions, mutations and getters into separate files like this:

└── src
     ├── assets
     ├── components
     └── store
           ├── store.js
           ├── actions.js
           ├── mutations.js
           └── getters.js

store.js

import Vuex from 'vuex';
import Vue from 'vue';

import actions from './actions';
import getters from './getters';
import mutations from './mutations';

Vue.use(Vuex);

export const store = new Vuex.Store({
  state: {
    someObj: {},
  },
  actions,
  getters,
  mutations,
});

actions.js

const actionOne = (context) => {
  ...
  context.commit('PROP1_UPDATED', payload);
};

const actionTwo = (context) => {
  ...
  context.commit('PROP2_UPDATED', payload);
};

export default {
  actionOne,
  actionTwo,
};

mutations.js

const PROP1_UPDATED = (state, payload) => {
  state.someObj.prop1 = payload;
};

const PROP2_UPDATED = (state, payload) => {
  state.someObj.prop2 = payload;
};

export default {
  PROP1_UPDATED,
  PROP2_UPDATED,
};

getters.js

const prop1 = state => state.someObj.prop1;
const prop2 = state => state.someObj.prop2;

export default {
  prop1,
  prop2,
};

...then you are able to do stuff from within your components as you please using the usual this.$store.dispatch('actionOne') ...

Upvotes: 45

Bill Criswell
Bill Criswell

Reputation: 32921

You can break them into different modules. That way you can keep all related mutations, getters, state and actions in separate files. The documentation explains it better than I can: https://vuex.vuejs.org/en/modules.html

Upvotes: 15

Related Questions