A New Way to Write Vuex Module

Matheus Ale da Silva
3 min readJun 26, 2021

--

Since I have started using Vuex I feel that there is a big mistake in the modules feature. Let’s talk about it and what I have done about it.

First of all, this post is to explore the reasons why I have written the vue-tools package.

What I think is Wrong with Vuex Module?

Into Vuex’s documentation page, to dispatch a module’s action we had to pass the module name and the action name as action type, like:

store.dispatch(‘module/action’)

Looks great and simple, right?! but there are some big issues:

  • Wich argument that action is expecting?
  • Where is this action implementation?

In the real world, with many developers working on a fast-growing project we have to rename modules; move codes and files; delete things that we don't need any longer. When dealing with code refactoring, we will find out that the hardest job is finding all references and uses of getters and actions. Even using typescript and modern code editors won’t help you in anything.

To work on those problems I have seen people creating modules like this:

I agree that this solves the code reference problem, but it is ugly! I think so. Imagine that there are many actions and mutations in a real word module to change loading and errors flags.

With these problems in mind, I had started my research for packages that come up with a new approach to define the Vuex modules. I found just one: vuex-module-decorators. It uses class and decorators to define modules. It's a good way to do it, but I don't like to use class. Personally, I prefer a functional style, even Vue 3 will use functional methods -the composition API- to create the component instance.

My Proposal to Solve Those Problems

My package vuex-tools solve it and also, make it easier to create modules. take a look:

Don't forget to read the comments. has a lot of explanations too.

If you are fast, you already noticed that using typescript and a modern code editor is advantageous for you. let’s highlight some points:

  • Easy goto implementation just by vscode control+clicking into the function name.
  • Easily find all uses of an action;
  • Type for actions arguments and mutations also getters (more about getter later);
  • All state type in just one place.

As you have seen, my package just have two functions createModule and createState. The first one is the heart of this package because it implements the interface ModuleBuilder, it’s an API to create an module incrementally. And createState builds modules and creates an instance of the Vuex Store as you are used to.

The interface ModuleBuilder have 3 functions that you can use: action, mutation and getter. I think you know what they can do for you. action and mutation return another function that expects an argument (or not) and returns an object. This return is passed to store$dispatch or store$commit and Vuex will know what to do with it. getter is different, look how to use it:

const getSortedItems = moduleBuilder.getter<Item[]>(
'sortedItems',
(state) => [...state.items].sort(a, b) => a.order - b.order
);

// vue component
{
computed: {
sortedItems() {
getSortedItems(this.$store.getters)
}
}
}

We pass the store$getter to returned function of ModuleBuilder$getter call, and it returns the getter value.

If you have read this far, thank you very much! And I would be glad to have your clap and feedback about what I have done, also I am open to answer issues on Github and receive Pull Request of any kind.

My next steps for improving these libraries are:

  • Remove from beta;
  • Refactor the code to a more readable one ( createModule is a mess I know);
  • Improve DOCS with more examples;
  • 100% test coverage and add more cases;
  • Test with Vuex plugin;
  • Be referenced into Vuex documentation;

--

--

Matheus Ale da Silva
Matheus Ale da Silva

Written by Matheus Ale da Silva

I am A full-time coder and sometimes I go around to do what normal people do.

No responses yet