Photo by Louis Moncouyoux on Unsplash

When developing a Vue app in one large file we have the advantage of having the whole application state in one place — in data object on Vue components instance. As soon we start to modularize the application by splitting it into child components we face the challenge of state management between the parent and child, and between sibling components.

In my previous articles, I’ve explained one of the solutions to this challenge — an EventBus pattern. Even though EventBus is quite simple to set up and start to use I find it fits better to more complex applications. For example, in applications where communication should happen between components with different ancestors and with deeper nesting.

In simpler applications where there is s single parent component composed of child components, an EventBus could be too much to set up for handling simple events. Instead, we can use the built-in features of Vue like props and events — a props-down and events-up communication pattern.

The flow of props and events inside a Vue.js component

First, every Vue component maintains its own state in the data property. In the props-down and events-up pattern, the parent component’s data object is the single source of truth for the whole application. Child components should receive data from the parent’s data object via props — “props-down”. And parent component should update its state by handling events emitted from child components — “events-up”.

Here you can see an implementation of this patter which is a counter app.

The App.vue is the parent or root component which holds the information or state about the current count, labels for two buttons, and messages array. Also, it has defined two handler messages which are bound to child components by the event name @buttonClicked . So every time the child component will emit a button clicked event it will be handled by the App.vue components — it will decrease or increase the current count and log message coming from child component.

Both of the child components do the same. First, they receive the textual label to display and a count — which in this case is increased or decreased and added to the message to demonstrate that message can be a non-primitive type also.

The child components’ responsibility is to handle the @click event and to emit buttonClicked event. By using this.$emit("buttonClicked") everywhere the button component is implemented the parent component can now bind to the @buttonClicked and act upon the occurrence of an event.

This is it. Now you have another tool in your Vue.js toolbox to communicate between components via parent component by receiving props and emitting events.

Cheers!