How to Pass Data from Child to Parent in Vue: Simple Guide
In Vue, you pass data from a child to a parent component by using the child's
$emit method to send a custom event with data. The parent listens for this event with @eventName and receives the data as an argument in the event handler.Syntax
Use $emit('eventName', data) inside the child component to send data. The parent listens with @eventName="handlerMethod" on the child component tag. The handler method receives the data as a parameter.
- $emit: Sends a custom event from child to parent.
- eventName: Name of the event to listen for.
- data: The value or object sent to the parent.
- @eventName: Parent listens for the event.
- handlerMethod: Parent method to handle the data.
vue
<!-- ChildComponent.vue --> <template> <button @click="sendData">Send Data</button> </template> <script setup> const emit = defineEmits(['customEvent']) function sendData() { emit('customEvent', 'Hello Parent!') } </script> <!-- ParentComponent.vue --> <template> <ChildComponent @customEvent="handleData" /> <p>Received: {{ message }}</p> </template> <script setup> import { ref } from 'vue' import ChildComponent from './ChildComponent.vue' const message = ref('') function handleData(data) { message.value = data } </script>
Output
Button labeled 'Send Data' and below it text 'Received: ' which updates to 'Received: Hello Parent!' after clicking the button.
Example
This example shows a child component sending a string to its parent when a button is clicked. The parent updates its displayed message with the received data.
vue
<!-- ChildComponent.vue --> <template> <button @click="notifyParent">Click Me</button> </template> <script setup> const emit = defineEmits(['notify']) function notifyParent() { emit('notify', 'Data from child') } </script> <!-- ParentComponent.vue --> <template> <ChildComponent @notify="receiveData" /> <div>Message from child: {{ childMessage }}</div> </template> <script setup> import { ref } from 'vue' import ChildComponent from './ChildComponent.vue' const childMessage = ref('') function receiveData(data) { childMessage.value = data } </script>
Output
Button labeled 'Click Me' and below it text 'Message from child: Data from child' after clicking the button.
Common Pitfalls
Common mistakes include:
- Not defining the event name in
defineEmitsin the child component. - Using the wrong event name in the parent listener.
- Trying to directly modify parent data from the child instead of emitting events.
- Not passing the data as an argument in
$emit.
Always use $emit to send data upward and listen with the exact event name.
vue
<!-- Wrong: child emits event without defining it --> <script setup> // Missing defineEmits function send() { emit('update', 'data') // emit is undefined } </script> <!-- Correct: defineEmits used --> <script setup> const emit = defineEmits(['update']) function send() { emit('update', 'data') } </script>
Quick Reference
- Child: Use
const emit = defineEmits(['eventName'])andemit('eventName', data). - Parent: Listen with
@eventName="handler"on child component. - Handler: Receives data as argument to update parent state.
Key Takeaways
Use the child's $emit method to send data upward with a custom event.
The parent listens for the event using @eventName and handles the data in a method.
Always define emitted events with defineEmits in the child component.
Never try to directly change parent data from the child; use events instead.
Match event names exactly between child emit and parent listener.