7. Data Flow between Components in Vue.js
By: Vrijraj Singh
Tags: Vrijraj, Vuejs, Vue, Vue Component, Techferment

Just like any other application, the Components organization goes like a nested tree. For example, a simple website that includes a header, sidebar, and some other components in a container. The organization of the component would be like this.

Data Flow between Components

There can be two types of data flow between components:

Parent component to Child Component Child component to Parent Component

We can send data from the parent component to the child component using props. Child Component to Parent Component We can send data by emitting an event from the Child component and listen to it on the other end (Parent component).

Parent component to Child Component

As I mentioned that we can send data from the parent component to the child component using props.

Props are the way components can accept data from components that include them (parent components).

// hello.vue Component

<template>

<h1 class="title">Vue.js Component | {{msg}}</h1>

</template>



<script>

export default {

name: 'HelloComponent',

props: ['msg'],

data: ()=>({

}),

methods:{

}

}

</script>



<style>

.title{ color: red }

</style>

Accept multiple props

You can have multiple props by appending them to the array:

props: ['msg','fullName', 'age'],

Set the prop type

You can specify the type of a prop by using an object instead of an array, using the name of the property as the key of each property, and the type as the value:

props: {

firstName: String,

lastName: String

},

The valid types you can use are:

String

Number

Boolean

Array

Object

Date

Function

Symbol

When a type mismatches, Vue alerts (in development mode) in the console with a warning.

Prop types can be more articulated.

You can allow multiple different value types:

props: {

firstName: [String, Number],

lastName: String

},

Set a prop to be mandatory

You can require a prop to be mandatory:

props: {

firstName: {

type: String,

required: true

}

},

Set the default value of a prop

You can specify a default value:

props: {

firstName: {

type: String,

required: true,

default: 'Unknown person'

}

},

for object

props: {

name: {

type: Object,

default: {

firstName: 'Unknown',

lastName: ''

}

}

},

You can even build a custom validator, which is cool for complex data:

props: {

name: {

validator: name => {

return name === 'TechFerment' //only allow "TechFerment"

}

}

},

Passing props to the component

You pass a prop to a component using the syntax

<ComponentName color="white" />

if what you pass is a static value.

If it’s a data property, you use

<template>

<ComponentName :color="color" />

</template>



<script>

//... import component

export default {

//... register component

data: ()=>({

color: 'white'

}),

//...

}

</script>

You can use a ternary operator inside the prop value to check a truthy condition and pass a value that depends on it:

<template>

<ComponentName :color="color == 'white' ? true : false"/>

</template>



<script>

//... import component

export default {

//... register component

data: ()=>({

color: 'white'

}),

//...

}

</script>

Child component to Parent Component

Child Component to Parent Component We can send data by emitting an event from the Child component and listen to it on the other end (Parent component).

Here is the syntax for the child component for the emitting events.

// Without parameters(data)

this.$emit('eventName') // With Parameters(data)

this.$emit('eventName', param1, param2)

In this syntax, we need to be careful while giving a name to the event because using the same name; we will later listen to this event. In order to listen to this event, we can listen to it as we listen to a click event in Vue.js. For example

<myComponent @eventName="doSomething"></myComponent>

Example

// Child Component <script>

export default {

name: 'CarChildComponent',

methods: {

handleClick() {

this.$emit('clickedSomething')

}

}

}

</script>

The parent can intercept this using the v-on directive when including the component in its template:

<template>

<div>

<Car v-on:clickedSomething="handleClickInParent" />

<!-- or -->

<Car @clickedSomething="handleClickInParent" />

</div>

</template>



<script>

export default {

name: 'App',

methods: {

handleClickInParent: function() {

//...

}

}

}

</script>

You can pass parameters of course:

// Child Component <script>

export default {

name: 'ChildComponent',

methods: {

handleClick() {

this.$emit('clickedSomething', param1, param2)

}

}

}

</script>

and retrieve them from the parent:

<template>

<div>

<Car v-on:clickedSomething="handleClickInParent" />

<!-- or -->

<Car @clickedSomething="handleClickInParent" />

</div>

</template>



<script>

export default {

name: 'App',

methods: {

handleClickInParent(params1, params2) {

//...

}

}

}

</script>

Keep watching this and follow us for more tech articles or you can reach out to me for any doubt and suggestions and the next blog in the series will be published soon.

Thanks

Happy Coding!