Vue.js Components Communication Patterns (without Vuex) - Part 2
Tags: vue, javascript, webdev
Published: 2021-11-22 22:49:03

***$parent and $children patterns***

In [Part 1](https://csdigitalnomad.medium.com/vue-js-components-communication-patterns-without-vuex-part-1-e9da6a0285ac) of this series, we introduced two patterns that work perfectly in a two-level component hierarchy, but what about a three-level or even four or five-level hierarchy? 
Now following the starting examples of [Part 1](https://csdigitalnomad.medium.com/vue-js-components-communication-patterns-without-vuex-part-1-e9da6a0285ac), 
let's add a new component `GrandchildA`, and here is the initial state of the three components:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xv581p9awf4vnlo3lza0.png)

`Parent` has a `ChildA` component that gets an `input` event bound onto its tag. This is the "custom v-model" pattern discussed in [Part 1](https://csdigitalnomad.medium.com/vue-js-components-communication-patterns-without-vuex-part-1-e9da6a0285ac).

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i3pzcne8n9c0omj305k0.png)

Similar to `Parent`, `ChildA` now has a `GrandchildA` component that gets an `input` event bound onto its tag, and it passes the `desserts` data it receives from `Parent` into `GrandchildA`. Notice the watch function for its prop `value` at line 38, this is to make sure whenever the prop changes, `ChildA.desserts` will get the latest value.

Also, `GrandchildA` will pass its data to `ChildA`, and `ChildA` will pass it back to `Parent`, as seen in lines 43 - 46.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xgjp1i72c55yiaynbl1p.png)

`GrandchildA` has the same settings as `ChildA` in [Part 1](https://csdigitalnomad.medium.com/vue-js-components-communication-patterns-without-vuex-part-1-e9da6a0285ac), it has a button where we can add a new dessert. 
In the event handler function `handleUpdate`, it will use `$emit` to trigger the `input` event bound onto it in `ChildA`, and pass the new data as the argument.

Here is the current view:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lph4y2mhraoezxhu1f69.png)

Now if the user clicks the `Update` button on `GrandchildA`, the view becomes:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yzi52san9p9odz1isze1.png)

`GrandchildA` sends the updated `desserts` to `ChildA` by `this.$emit('input', this.desserts)`, and `ChildA` does the same and passes the data to `Parent`, `Parent` updates its `this.desserts` using the new value, and passes it down to `ChildA` as a prop. `ChildA` is watching the prop value change, so it will update its `this.desserts`, and `this.desserts` is passed down to `GrandchildA` as a prop.

So in order for `GrandchildA` to communicate with `Parent`, it must go through the middle man `ChildA`. How about now we add a `GrandGrandchild` component? It will follow the same approach, and both `ChildA` and `GrandchildA` will become the middle man. When it comes to a multi-level hierarchy, we can repeat the two patterns from [Part 1](https://csdigitalnomad.medium.com/vue-js-components-communication-patterns-without-vuex-part-1-e9da6a0285ac) in each descendant component, but there is a better way.

## $parent pattern
Now let's modify `GrandchildA.handleUpdate()`:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y480kaaqvt4z5okxggmb.png)

Thanks to the exquisite design of Vue, we don't really need to trigger the `input` event on `GrandchildA` and then execute the callback function in `ChildA`. Instead, in `GrandchildA` we can directly trigger the `input` event on `ChildA` using `this.$parent` to execute the callback function in `Parent`, because `GrandchildA.$parent` = `ChildA`. Super simple, isn't it?

Since we don't need `ChildA` to do the middle man work anymore, now `ChildA` can be very simple:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wyhv4yydgsnji9999xfx.png)

`ChildA` becomes to only receive a prop and pass it to `GrandchildA`. If we click the `Update` button now, it works the same:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y9aelg8s5dpa8uffkqay.png)

The new `desserts` data is updated from `GrandchildA` directly to `Parent`, then passed down to `ChildA` and `GrandchildA`.

## $children pattern
In a Vue component tree, there is `$parent`, and of course, there is `$children` as well. Let's see an example of `$children`. We will leave `GrandchildA` as is, while in `ChildA`, now we bind a new event named `show:alert` onto the `GrandchildA` tag:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fflofqwvp5nsr54eev41.png)

And the event callback function is `handleShowAlert` which will show an alert. Now in `Parent`, let's add a new button:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aiq00x3eigpt44yow7dr.png)

When clicking the button, we want to trigger the `show:alert` event on `GrandchildA`, which will, in turn, execute `ChildA.handleShowAlert()` to show the alert. This is achieved using:
```javascript
this.$children[0].$children[0].$emit('show:alert');
```
Because `$children` is an array of VueComponent instances and there is only one child for both `Parent` and `ChildA`, we can use `$children[0]`.
Now if the user clicks the button:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ub1s2jkxgv43xz67vtcm.png)

An alert is shown as expected.

## Conclusion
For a multi-level hierarchy of components, the "$parent and $children" patterns are suitable as they can reduce the level-by-level data passing between components. But if there are too many levels, then we would have to do something like this:
```javascript
this.$parent.$parent.$parent.$parent.$emit('input', this.desserts);
```
Also, a parent component can have many children components, and each child component can have its many children components. How can we pinpoint a specific child component in the `$children` array? This question will lead us to [Part 3](https://csdigitalnomad.medium.com/vue-js-components-communication-patterns-without-vuex-part-3-5ccfdbe3ecfa) of this series where we will look to solve it.

Here are all the articles in this series:

***[Vue.js Components Communication Patterns (without Vuex) - Part 1](https://csdigitalnomad.medium.com/vue-js-components-communication-patterns-without-vuex-part-1-e9da6a0285ac)***

***[Vue.js Components Communication Patterns (without Vuex) - Part 2](https://csdigitalnomad.medium.com/vue-js-components-communication-patterns-without-vuex-part-2-7f9c0bc132a2)***

***[Vue.js Components Communication Patterns (without Vuex) - Part 3](https://csdigitalnomad.medium.com/vue-js-components-communication-patterns-without-vuex-part-3-5ccfdbe3ecfa)***

***[Vue.js Components Communication Patterns (without Vuex) - Part 4](https://csdigitalnomad.medium.com/vue-js-components-communication-patterns-without-vuex-part-4-f99a17bd98f0)***

***[Vue.js Components Communication Patterns (without Vuex) - Part 5](https://csdigitalnomad.medium.com/vue-js-components-communication-patterns-without-vuex-part-5-2cf6fb1c5e26)***

***[Vue.js Components Communication Patterns (without Vuex) - Part 6](https://csdigitalnomad.medium.com/vue-js-components-communication-patterns-without-vuex-part-6-10e4e43f0ac7)***

***[Vue.js Components Communication Patterns (without Vuex) - Part 7](https://csdigitalnomad.medium.com/vue-js-components-communication-patterns-without-vuex-part-7-15c5b786539e)***