Vue data flow — How it works?
When I was learning Vue, one of the hardest things was understanding how Vue data flow works. EventBus, Vuex, Props… What are all of those? Which one should I use?
Let’s learn their differences and when to use each one of them.
Inside the component
Here’s the HTML part:
As you can see, it’s pretty simple. Only two methods are used here, the first to add and the latter to remove To-Dos.
At the 23rd line of the HTML section, you’ll find an “on-click” function to switch the current To-Do between finished and not finished states and at line 25 another to set the current To-Do to editable, but the Two Way Data Binding does everything.
But what if we have two components in different places? Or three? What if one component is the parent of the other one and we need to pass down and up information?
Props and $emit — For parents and children components
Let’s say we have a view divided into multiple components, with child components within components, just like this:
As you see, the orange-yellow main component acts as the root of every component. Inside has 3 components, red, violet and green. Some of the components have a child component inside them, making it a 3 level web application.
What if you want to pass information from the red component to one of the child green component. How would you do it?
You can send information to the parent with $emit and then to the child with props. It would look like this:
This is how I used $emit and props:
A bit complex but it is really easy once you get the hang of it. Send your data up with $emit, and down with props. That’s it.
But what if we want to send the information between components with several levels between them? Do we create 4 $emits and 2 props?
Well, we can. That would be crazy.
Better use EventBus.
EventBus — From anywhere to anywhere
The Global EventBus works as a “Parent of all components”. This component will have access to all components where it’s loaded.
Instead of going up and down components to send the information, we can send an event to EventBus and set the components we want to listen to that event.
From one component to EventBus and from it to the component. Without components listening to events we don’t need
This is how it works:
Easier, right? Just add a Vue component called ‘EventBus’ to your main.js, and use it as a way to send/receive signals from components.
While this is a great way to work from small to medium sites, when we want to get serious, we need to use Vuex
Vuex — Our state manager
Vuex is the Vue state management pattern for Vue.js applications.
Think about it like a centralized data storage or a “Single source of truth”.
Vuex acts as a single central store for all the components in one application. Also, keeps track of all the methods (or mutations) used and helps you to manage all the data in your web application.
If you use Vue Devtools you get to use their cool features like tracking or watching all the data stored in Vuex.
Here you will see the methods triggered, what data and methods has currently the Vuex store, and can go back to retrace your steps, modify the current data, etc.
While it makes the web application a bit more complex adding overhead, it helps a lot with the separation of all the logic into a single file, granting access to multiple independent components and more.
Let’s see how I used it in a real setting:
Pretty easy again. We load all the functions and data a the store.js file which will be our “Single source of truth”. Then, on each component it is needed, we will load the parts we need.
Which one should I use?
As many questions…it depends.
You can use any of them at your project, but each one is suited for a different scenario.
- Props and $emit: If you have a few components next to each other. Props work great when you have multiple components but we need to pass different data (for example, we have 4 tables with different datasets in each one)
- EventBus: If you have more than a few components, if your web app structure sets your components more horizontal (sibling components instead parents) than vertically and to trigger functions (For example, to activate a notification)
- Vuex: If you have a medium to a large web app, where you have complex logic and when you want to track all the mutations of your data, call to APIs, etc
The experience will teach you when to use each one.
For example, I use Vuex in every app, even in smaller ones (I love to keep track of my data), EventBus to trigger functions on certain events and props when I create a component that I use multiple times with different data.
Reading (and writing) about what data-flow techniques we can use was cool, but you need to practise. I wrote a small post more, more code-oriented than this one where I explained the theory. You can read it here: Passing data in Vue
And, of course, we have the Vue docs that are great: