Being able to pass data around your application is extremely important.
There are 3 main types of communication we care about in Vue:
It seems that child to child data sharing is where most of the confusion and frustration lay. Parent to child and child to parent are much easier to figure out.
So how do we do it?
** The short answer: you don't pass data from one child component to another child component. **
Of course, that's not a very satisfying answer — or helpful one either.
Let me explain what I mean.
The first principle of data flow in Vue is this:
Data flows down, never up.
This is what props are for, and why we can't mutate them. Mutating them would be sending data from the child to the parent, and we have a different mechanism for that.
The second principle of data flow is this:
Events are emitted up.
These two principles allow us to send data down the component hierarchy, as well as back up.
They take care of the first two types of component to component communication: parent to child, and child to parent.
Might we find a third principle that helps us with child to child communication?
Nope.
So how do we pass data between two child components, components that are siblings?
What we have to do is to stop treating them as siblings, and break that relationship down into it's parts.
If you have a sibling, they are the child of your parent.
The same goes for components.
To communicate from one component (B
) to its sibling component (C
), we first communicate with the parent (A
), which then communicates to the sibling component (C
).
A/ \B C
Let's look at an example.
Here we have a Toggle
component, which shows or hides a piece of content on the page. We also have a Button
component that we want to communicate with the Toggle
, to switch it between open and closed:
// Parent<template><div><Toggle :open="true">Show or hide this content!</Toggle><Button @click="">Toggle the content</Button></div></template>
To follow this pattern we need to:
Button
to the parentToggle
componentBased on the principles of data flow which we just covered, this means we must:
Button
componentToggle
componentThis is how we would make that work:
// Parent<template><div><Toggle :open="isOpen">Show or hide this content!</Toggle><Button @click="isOpen = !isOpen">Toggle the content</Button></div></template>
By adding the state isOpen
to the parent, we can facilitate communication between the two sibling components.
When the Button
component is clicked it emits an event that updates the isOpen
variable. That variable is then passed down to the Toggle
component as a prop.