​​Editor’s note: This article was updated on 4 April 2022 to demonstrate modifying component data using Vue.js v.3 and Composition API.
This article will demonstrate how data and its state can be passed from a child component to its parent component in Vue.js using event emitters. We’ll start with a review of passing data through components, and then we’ll jump into our demo. Our demo will cover the following:
This post is suited for developers of all stages, including beginners. Here are a few things you should already have before going through this article:
If you don’t have Vue CLI already on your machine, install it with the following command:
npm install -g @vue/cli
Next, create a new project, event-emitters
, like so:
vue create event-emitters
Make sure to select Vue 3 when creating the app.
Then, cd into the app folder and kickstart the app using:
cd event-emitters
npm run serve
In this article, we’ll be using Composition API to demonstrate how to emit data to parent components through events. This allows us to pass certain data to the parent component when triggered by an event, such as onClick
or keyup
.
To pass data values from parent components (like the app.vue
) to child components (like nested components) inside the app component, Vue.js provides us with a platform called props. Props are custom attributes that we can register on a component. With props, we can define data in the parent component, give it a value, and then pass the value to a prop attribute that can then be referenced down in the child components.
This post will demonstrate the reverse of this process. In this tutorial, we’ll update data values in a parent component from the child component. We’ll use the emit construct to handle event emission and updating of data.
We’ll walk through the process of emitting events from a child component, setting up listening on the parent component in order to pass data from the child component, and then finally updating the data value.
Getting started
In the folder, you will find two components: parentComponent.vue
and childComponent.vue
, with the root component being the app.vue
file. Your childComponent.vue
file should look like this:
<template> <input v-model="inputValue" @keyup="inputChange"/> </template> <script> import {ref} from "vue" export default { name: "ChildComponent", setup(props, context) { const inputValue = ref("") const inputChange = ()=> { context.emit("newValue", inputValue.value); }; return { inputChange, inputValue }; }, emits:["newValue"] }; </script>
For this demo, we want to pass on the child component behavior to the parent component so that on click, every title nested in the parent component changes.
To do this, we need to create an emitter that will emit an event in the child component that the parent component can listen to and react. This is the same as event listener logic for components.
We have an input
element that’s binded to inputValue
. Next, we use the @keyup
event to trigger our inputChange
function. We use this function to emit our input value in real time using inputValue
. To do this, we pass context
into our setup
and emit the data as follows:
context.emit("newValue", inputValue.value);
By doing this, we name the event newValue
and add it to our emits
array:
emits:["newValue"]
Now, we can pass the input value to the parent component on keyup
using newValue
.
The next thing to do after an event is created is to listen to it and respond.
Let’s go to your parentComponent.vue
file. It should look like this:
<template> <div> <h3>Input: {{ title }}</h3> <child-component @newValue="changeTitle" /> </div> </template> <script> import ChildComponent from "./childComponent.vue"; import {ref} from "vue" export default { name: "ParentComponent", components: { ChildComponent }, setup() { const title = ref(""); const changeTitle = (newTitle) => { console.log("fire") title.value = newTitle; }; return { title, changeTitle }; }, }; </script>
In the above code, we import our child-component
into our parent component.
Then, we add @newValue="changeTitle"
to tell the component to listen to changes on the child and trigger our changeTitle
with the new data.
Next, we declare title
using ref
and assign the new child input data to title
as the user types:
const title = ref(""); const changeTitle = (newTitle) => { console.log("fire") title.value = newTitle; };
Finally, we display the user input in the parent component using title
.
<h3>Input: {{ title }}</h3>
It’s important to note that as data passes through the emitter to the parent component, the data in any components nested in the parent component also re-renders and updates.
If you followed this post from the start, you can download or clone the demo project in VS Code. The demo of the finished project is shown below:
Hopefully, this article introduced you to another interesting side of using events in Vue with emitters: creating an event in one component and listening to and also reacting to it in another component. This can have many use cases that will be really beneficial in your workflow. Happy coding!
Debugging Vue.js applications can be difficult, especially when there are dozens, if not hundreds of mutations during a user session. If you’re interested in monitoring and tracking Vue mutations for all of your users in production, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording literally everything that happens in your Vue apps, including network requests, JavaScript errors, performance problems, and much more. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred.
The LogRocket Vuex plugin logs Vuex mutations to the LogRocket console, giving you context around what led to an error and what state the application was in when an issue occurred.
Modernize how you debug your Vue apps — start monitoring for free.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowDing! You got a notification, but does it cause a little bump of dopamine or a slow drag of cortisol? […]
A guide for using JWT authentication to prevent basic security issues while understanding the shortcomings of JWTs.
Auth.js makes adding authentication to web apps easier and more secure. Let’s discuss why you should use it in your projects.
Compare Auth.js and Lucia Auth for Next.js authentication, exploring their features, session management differences, and design paradigms.