Extending VueX knowledge: modules

Posted by in Javascript and TypeScript

In the third entry of the Working with Vuetify series (part 2) I told you about VueX, the information repository used to work with VueJS, and which is very practical (in my opinion). Today we are expanding our knowledge with the use of VueX modules.

VueX in large projects

Although in the title I have put VueX for big projects, the explanations that I describe below are also useful for medium type projects, or even small projects. There is no perfect recipe, but what I tell you here is based absolutely on my experience, and on what has worked for me.

When I work on a project, regardless of the job, I usually have the following organization:

  • API: the place where the API of the app is developed
  • components: I have several components that I reuse in several projects. Here, I include message boxes, or input boxes, login component, ….
  • components2: here I have the exclusive components of the project
  • css: add here all style sheets
  • img: is for the images
  • js: you can add all Javascript’s libraries, in case you are not using a CDN and you’d prefer to have it local
  • mixins: add here all Javascript’s files used as mixins not only for components2 but also for store2
  • routes: add here all relative to vue-router
  • store: files that are part of the store that are shared by different projects
  • store2: files that are included on the store of the app
  • utils: other Javascript’s files you need to use

Since the vast majority of developments I do against databases, it is possible that within each directory there is a subdirectory for each table. This is the way I do in the API subdir, while I usually develop in each file the specific components for each table, and I include them all.

As an example, if I have a table called provincias, in the api dir I have a subdir called provincias as well, also, I have a provincias.js file in store2 and another provincias.js in components2.

Over time, I have created a number of basic components that I reuse very often: for example, for dictionary tables, I have an exclusive one.

I might guess, my dear reader, that you will end up doing something similar when structuring your projects, but this is my way.

Let’s go back to the store, and here is how I prepared a module.

The module test.js in Vuex

When the store is complicated because the information to be stored is wide or we want to distribute the information better, there is the possibility of using modules, which allows to order such information. And this is what has been done with store/test.js, which is a module that has been added.

The modules also includes their own store, getters, actions and mutations, and although it seem difficult to understand, it is the base to work with large apps.

The code for store/test.js is:

// Vuex test 1.3.6 - 20200702

// Constantes 
const test_null = {};
const test_search_null = {};

const test_actions = {
	listing: async function({commit, getters, rootState, rootGetters, dispatch}, query) {
		// include API calls
	},
	view: async function({commit, getters, rootState, rootGetters, dispatch}, query) {
		// include API calls
	},
};

const test_state = {
	base: {
		tabla: 'test', 	// CONFIG - Tabla
		campo_id: 'idcanon', // CONFIG - Campo ID
	},
	search: test_search_null,
	regs: [],
	num_regs: 0,
	registro: null,
};

const test_getters = {
	error: state => `${state.base.tabla}`,
	table: state => state.base.tabla,
	campo_id: state => state.base.campo_id,
	// raw: state => state.raw,
};


const test_mutations = {
	num_regs: set('num_regs'), // set para asignacion SIMPLE
	regs: setbase('regs'),  // setbase para incluir
	registro: setbase0('registro'),
	clear(state) {
		state.registro = test_null;
		state.regs = [];
		state.num_regs = 0;
	},
	clean(state) {
		state.registro = test_null;
	},
	reset(state) {
		// state.search.campo_i = 0;
		// state.search.campo_s = '';
	},
	// Exclusivas de test
	// campo_i: function(state, val) { state.search.campo_i = val; },
	// campo_s: function(state, val) { state.search.campo_s = val; },
};

const test = {
	namespaced: true,
	state: test_state,
	mutations: test_mutations,
	getters: test_getters,
	actions: test_actions
};

Basically, for the development of a store module I develop variables with very specific names for the development of what I need (and that varies, or can do so, from one module to another). At the end, I create a variable, in this case it is test, where I associate the states, actions, mutations and getters. Also, that test variable is the one that has to be included in the state declaration.

Also, the property namespaced should be set to true, because I want vueX to treat it as a module, and for using it, you need to proceed like this:

  • dispatch(‘test/listing’)
  • commit(‘test/registro’, {})

But there’s still one more step, and that’s to prepare the store so that you can use the module. In this case, we’ll go back to store/_index.js and modify it like this:

const store = new Vuex.Store({
	strict: true, // en development
	state,
	getters,
	mutations,
	modules: { // Your store-modules
		test,
	}
})

A little help for the store: state-mutators.js

When I was learning about VueX I found this entrance where I got some recommendations when working with mutations, and by now, I have include several more for covering my own needs (you can add yours). In order to use it, you nned to load it, and this is one of the files I have included in the utils subdir.

Regarding the Working with VueX project, despite having uploaded several Javascript files and expanded the Store, we haven’t used anything yet. We’ll see that later!

My personal opinion about VueX

Honestly, I find VueX almost mandatory for any VueJS project that involves working with data, and although it may seem messy, I assure you that it is very well thought out, and it works. The fact that it is strict and requires a specific workflow makes it more difficult to make mistakes.

Over time, I’ve also developed specific variables to work with VueX that greatly accelerate development since they have allowed me to reuse them in many places, and to have a fairly reliable structure, where I have a lot prepared in advance. In addition, the error detection makes that when corrected, it is automatically corrected in all the sites where they are used, but in addition, it allows me to extend with options in case it is necessary, in a single site, being available for the rest of the projects.

And, that’s all. I encaurage you to learn VueX modules when using VueJS because they are very useful, specially when the project is a large one!

Happy coding!