Mobx- The Vue way
Yet another Todo List
So, in one of my projects in Vue, I wanted to try another path about state management pattern, as an addition (for now) of VUEX.
Although in my personal opinion, I think Vuex is fine and still believe that if something is built for a specific framework, then in a lot of cases, it should be a good reason to use it.
So why start to use Mobx?
I needed a sort of Model->View->ViewModel practice for building fields.
Mobx has been chosen, especially for its “framework-agnostic” idea and its built-in observable fields, simplicity, and very low boilerplate.
Mobx has a significantly better performance against other state management.
After searching a bit on the internet I didn’t find a good tutorial of how to use it with Vue Framework.
So I started to make a small “Todo List”, built with Vue & Mobx.
You can find my project in my GitHub :
To make things faster, I used vue-cli 3 for boilerplate.
This is my project structure, very simple, very minimalist.
I built 2 components, one is the list which is containing the todos, the other is the component for adding the todos.
Let's start with the store as simple as that, todo.js :
As we can see we import ‘observable’, this simple word does the “magic” for the observable fields in our class.
So we have a “Todo” class, with id, title, and isDone.
title+isDone are Observable fields because we are going to observe them in our component.
Then we have our todoList.js store:
Now we are importing, “@action” this decorator is for doing manipulation changes on the state.
In our case, we have “addTodo(title)” it is adding a new “Todo” to our state and “removeTodo(id)” which is changing the array of the todos by removing the currently selected todo id.
another decorator that we are importing is “@computed”. As you know already from Vue, computed is returning the state or some computed data from the state, without doing any changes in the store. Whenever you can you should use it because it's very optimized.
So in our getter “undones()” we put a “@computed” decorator to return the undone todos, this is the counter that shows the unfinished todos in our list.
The last decorator is “@observable” as we put in todo.js, we put it in our todos array property, that array will be observed in our components.
Now that we have built the store, let's start with the components.
First the “addTodo.vue” component:
Here we import “observer” from mobx-vue this time because the observer is in the part of our “framework” side, to bind between the component and the observables fields of the store.
Observer componentClass will make all our component reactive, means every change from the observable fields in the store will rerender our component.
As you can see we set the store in the data as a vm property, any access to the store will be from the vm.
As you can see we are listening to changes in vm.undones (the computed property getter from the store) and on adding a new title we are calling addTodo from the store, to create a new todo item.
For showing the todo list, we have another component, named “todoList.vue”:
Again, here we are importing the Observer componentClass to wrap it in our component, for observing any observable fields from the store, in this case, its the “todos” field from the store.
We run through our todos from the store and show them in our template.
This component is using the addTodo component for adding new to-do item in the list.
and that's it! :-)
I did that little app in very no time, just from reading a bit the guide from mobx guide.
Mobx is a really simple and quick state management library, there is some stuff that won't work in vue, means when you are using Mobx you can’t use the builtin “Computed” methods of vue, means all your computed should move to the store.
So if you still want to use Vue in the “VUE” way or the traditional way, i would recommend thinking again about the usage of this library.
I hope you enjoyed this article, this is my first article here so i will more than thankful if you have some notes, tips or feedback to give me :) even good ones! :)