컴포넌트 통신 기초 (Props & Emit)
Vue 애플리케이션은 작은 컴포넌트(부품)들의 조립으로 이루어집니다. 부모 컴포넌트가 자식에게 데이터를 물려줄 때는 Props(프롭스)를 사용하고, 자식이 부모에게 어떤 사건(이벤트)이 일어났다고 알릴 때는 Emit(에밋)을 사용합니다. 이를 단방향 데이터 흐름이라고 합니다.
<!-- ==========================================
// 📂 1. 부모 컴포넌트 (Parent.vue)
// ========================================== -->
<script setup>
import { ref } from 'vue';
// 자식 컴포넌트를 import 합니다.
import ChildComponent from './ChildComponent.vue';
const parentMsg = ref('부모가 용돈 5만원을 줌');
// 자식이 이벤트를 던졌을 때(Emit) 실행할 함수
const handleChildEvent = (replyMsg) => {
alert(`자식의 응답: ${replyMsg}`);
};
</script>
<template>
<div class="p-8 border-4 border-blue-300 rounded-xl m-4">
<h2 class="text-2xl font-bold mb-4">👨👩👧 부모 컴포넌트</h2>
<!--
:message="parentMsg" => Props 로 데이터 내려주기
@reply="handleChildEvent" => Emit 으로 올라오는 이벤트 받기
-->
<ChildComponent
:message="parentMsg"
@reply="handleChildEvent"
/>
</div>
</template>
<!-- ==========================================
// 📂 2. 자식 컴포넌트 (ChildComponent.vue)
// ========================================== -->
<script setup>
// [1. Props 받기]
// 부모가 전달한 속성 이름('message')을 배열에 명시합니다.
const props = defineProps(['message']);
// [2. Emit 준비하기]
// 부모에게 쏠 이벤트 이름('reply')을 배열에 명시합니다.
const emit = defineEmits(['reply']);
const sendToParent = () => {
// 부모에게 'reply'라는 이벤트를 쏘고, 뒤에 전달할 데이터도 같이 보냅니다.
emit('reply', '감사합니다! 다 썼어요!');
// 🚨 삐빅! Props로 받은 값은 절대 내 맘대로 수정할 수 없습니다 (읽기 전용).
// props.message = '내가 다 씀'; // 에러 발생!
};
</script>
<template>
<div class="p-6 border-4 border-green-300 rounded-xl bg-green-50">
<h3 class="text-xl font-bold mb-2">👶 자식 컴포넌트</h3>
<!-- 부모가 준 Props를 그대로 화면에 표시 -->
<p class="text-lg text-gray-700 mb-4">부모님이 주신 것: {{ message }}</p>
<button
@click="sendToParent"
class="bg-green-500 text-white px-4 py-2 rounded font-bold shadow hover:bg-green-600"
>
부모님께 응답 보내기
</button>
</div>
</template>