Modularization in Vuejs and Vuex

Eze Henry
The Startup
Published in
4 min readJun 12, 2020

When writing large front end applications, state management can be quite a difficult and tiring task.

For vue.js, a plugin named vuex was created for the purpose of state management. By default it comes with the folder structure:

the default folder structure of a vuex store

This folder structure could be used in small applications but if used in large applications the codebase would most likely look unreadable, dirty, and over time become difficult to handle.

Yeah I learned this the hard way

The recommended folder structure would be to break your store into various modules. Example:

The recommended vuex structure

This folder structure breaks down the store into modules with each of the modules having its own separate folder. The modules folder is positioned in the same folder as the index.js generated by vuex . As expected the content of the index.js file has to change too. e.g:

import Vue from "vue";import Vuex from "vuex";import state from './state.js'import actions from './actions.js'import mutations from './mutations.js'import getters from './getters.js'import user from './modules/user/index.js'Vue.use(Vuex);export default new Vuex.Store({state,mutations,actions,getters,modules: {user}});

In this example I created a module named “user”, I imported it into the index.js file provided by vuex. This way the user module has been connected to the store and can now be accessed.

Moving on to the “user” module we would be importing state, actions, getters, and mutations into the index.js file in this manner:

import state from './state.js'import mutations from './mutations.js'import actions from './actions.js'import getters from './getters.js'export default {namespaced: true,state,mutations,getters,actions,}

If you notice, the namespaced field was set to true, this is because we want to be able to specify the particular module to check for a particular action, state or getter as the case may be. Moving on….

State:

Due to the change from the default vuex structure to the vuex modular structure, the methods by which we access our vuex state has to change. e.g we won’t be able to access a userAvatar field from the user module’s state by just mapping userAvatar. So we would mapState in this manner in the component’s script:

<script>import {mapState} from 'vuex'export default {computed: {...mapState({userAvatar: state => state.user.userAvatar})},}
</script>

Above is the recommended method for accessing the state of a module, while the state of the module would look like this.

export default {userAvatar: "img-location"};

Actions:

We also can’t expect an action in the user module to be accessible by just mapping actions. We would have to specify the particular module we are trying to access. e.g

<script>import {mapActions} from 'vuex'export default {methods: {...mapActions("user", ["getUserInfo"]),userInfo() {
this.getUserInfo()
// you could either map it like we did above or call it the same way
// it was called below
this.$store.dispatch('user/getUserInfo')// this two methods execute the same task which is calling the //getUserInfo action}},}</script>

Above is the preferred method to access an action from a modular vuex while the actions file would look like this

export default {getUserInfo() {alert('Successful')}}

Mutations:

Mutations are used for non-asynchronous functions and most times used to mutate state. The method by which we access the mutation also has to change.

<script>export default {methods: {setuserInfo() {let data = {name: 'Henry'}this.$store.commit('user/setUserInfo', data)}},}

Above is the recommended method for accessing a mutation from a modular vuex while the mutation file would look like this

export default {setUserInfo: (state, data) => {
state.user = data
}}

Getters:

Getters are like the computed property of a component. They are used for calculations or filtering. A common use of getters is sorting out by the difference in fields or availability of fields. e.g:

export default {
getActiveUsers: state => {
return state.users.filter(x => x.active === true)
}
}

Above is the recommended method of declaring or writing a getter while it can be accessed by mapping getters in the computed property. e.g:

<script>import {mapState} from 'vuex'export default {computed: {...mapGetters('user', ['getActiveUsers'])},}
</script>

This was a long ride, hopefully, you were able to use the vuex modular store and write cleaner code.

--

--

Eze Henry
The Startup

I write about things I wish I knew previously. Mostly on technologies like Javascript, Vue.js, python, Node. https://godofjs.me/