Vue.js 2: Two-way data binding in Parent and Child components

Jithil Jishad
2 min readMar 3, 2019

One thing that Vue.js made easy for developers is two-way data binding with v-model directive. We don’t have to explicitly track the changes in the data and update everywhere it is being used. We all enjoy the freedom of having this facility. But we lack this freedom when it comes props which we use to transfer data from a parent component to a child component.

Vue.js does not allow two-way data binding between parent and child for obvious reasons. Because true two-way binding of props will cause maintenance issues as the child can change the parent data without the source of that change being obvious.

Hence, if we want to change the data in parent component as and when the child updates the data, the traditional and familiar way is to emit an event from the child component along with the new data and catch that event in parent component to update the data bound to the child.

Let us take a look at this approach.

Let us have a child component namely SampleComponent in our parent component. We bind parentData to this component, which will be passed down to the child.

The parent code will contain something like:

<SampleComponent :inputData="parentData" @update="parentData = $event;" />

And the child component will emit an event on update of the data in it.

<template>
<div>
<input type="text" v-model="inputData" @keyup="$emit('update',inputData);" />
</div>
</template>
<script>
export default {
name: "HelloWorld",
props: {
inputData: String
}
};
</script>

We are all familiar with this way of synchronizing the data between parent and child.

But Vue.js has made this a lot easier from 2.3.0+.

Vue.js has introduced a .sync modifier to v-bind which will make the above task a lot easier.

Just add this .sync modifier to the data binding in the parent and then in the child, just emit the update event. The data in the parent will also be modified with the new value.

Now the parent code will look like:

<SampleComponent :inputData.sync="parentData" />

And the input field in child will look like:

<input type="text" v-model="inputData" @keyup="$emit('update:inputData', inputData);"/>

That’s all! So easily done.

You can find a full example of the same in this codesandbox example.

Thanks for reading. Happy coding !!

--

--

Jithil Jishad

Full-stack developer | Design Thinking | .NET Tech Stack