728x90
오늘은 Vue.js에서 자주 사용되는 데이터 전달 방식인 prop과 emit을 활용해 부모 컴포넌트와 팝업(모달) 컴포넌트 간 데이터를 주고받는 방법을 알아보겠습니다. 특히, 부모 컴포넌트에서 팝업으로 초기값을 전달하고, 팝업에서 사용자가 선택한 데이터를 다시 부모로 보내는 과정을 코드와 함께 단계별로 설명해볼게요.
목표
-
부모 컴포넌트에서 팝업으로 초기 데이터를 prop을 통해 전달
-
팝업에서 선택한 아이템 정보를 emit으로 부모 컴포넌트에 전달
-
간단한 예제를 통해 동작 확인
1. 기본 구조 설정
먼저, 부모 컴포넌트와 팝업 컴포넌트를 만들어 보겠습니다. 부모 컴포넌트는 팝업을 열고 초기 데이터를 전달하며, 팝업 컴포넌트는 선택한 데이터를 부모로 보냅니다.
728x90
부모 컴포넌트 (ParentComponent.vue)
<template>
<div>
<h1>부모 컴포넌트</h1>
<p>선택된 아이템: {{ selectedItem ? selectedItem.name : '아직 선택 안됨' }}</p>
<button @click="openPopup">팝업 열기</button>
<PopupComponent
v-if="isPopupOpen"
:initial-data="initialData"
@close="closePopup"
@select-item="handleSelectItem"
/>
</div>
</template>
<script>
import PopupComponent from './PopupComponent.vue';
export default {
components: { PopupComponent },
data() {
return {
isPopupOpen: false,
initialData: { id: 1, name: '초기 아이템' }, // 팝업에 전달할 초기값
selectedItem: null, // 팝업에서 전달받은 선택값
};
},
methods: {
openPopup() {
this.isPopupOpen = true;
},
closePopup() {
this.isPopupOpen = false;
},
handleSelectItem(item) {
this.selectedItem = item; // 팝업에서 받은 데이터 저장
this.closePopup(); // 선택 후 팝업 닫기
},
},
};
</script>
<style>
/* 스타일은 생략 */
</style>
팝업 컴포넌트 (PopupComponent.vue)
<template>
<div class="popup">
<h2>팝업창</h2>
<p>초기 데이터: {{ initialData.name }}</p>
<ul>
<li v-for="item in items" :key="item.id" @click="selectItem(item)">
{{ item.name }}
</li>
</ul>
<button @click="close">닫기</button>
</div>
</template>
<script>
export default {
props: {
initialData: {
type: Object,
default: () => ({}),
},
},
data() {
return {
items: [
{ id: 1, name: '아이템 1' },
{ id: 2, name: '아이템 2' },
{ id: 3, name: '아이템 3' },
],
};
},
methods: {
selectItem(item) {
this.$emit('select-item', item); // 선택한 아이템을 부모로 emit
},
close() {
this.$emit('close'); // 팝업 닫기 이벤트
},
},
};
</script>
<style>
.popup {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: white;
padding: 20px;
border: 1px solid #ccc;
}
li {
cursor: pointer;
}
</style>
2. 코드 설명
부모 컴포넌트
-
initialData 전달: prop으로 initial-data라는 이름으로 초기 데이터를 팝업에 전달합니다. 여기서는 { id: 1, name: '초기 아이템' }을 예시로 사용했어요.
-
@select-item 이벤트 수신: 팝업에서 선택한 아이템을 받기 위해 handleSelectItem 메서드를 연결했습니다. 받은 데이터를 selectedItem에 저장하고 팝업을 닫습니다.
-
v-if로 팝업 제어: isPopupOpen 데이터로 팝업의 표시 여부를 조절합니다.
팝업 컴포넌트
-
props로 초기값 수신: initialData를 props로 받아 부모로부터 전달된 데이터를 표시합니다.
-
emit으로 데이터 전달: 사용자가 리스트에서 아이템을 클릭하면 selectItem 메서드에서 $emit('select-item', item)을 호출해 선택한 데이터를 부모로 보냅니다.
-
닫기 이벤트: close 메서드에서 $emit('close')를 호출해 부모가 팝업을 닫을 수 있도록 합니다.
3. 동작 확인
-
부모 컴포넌트에서 "팝업 열기" 버튼을 클릭하면 팝업이 열리고 초기 데이터가 표시됩니다.
-
팝업에서 리스트 아이템을 클릭하면 해당 데이터가 부모로 전달되고, 팝업이 닫힙니다.
-
부모 컴포넌트에 선택된 아이템 이름이 표시됩니다.
4. 마무리
이 예제는 Vue.js에서 prop과 emit을 활용한 컴포넌트 간 데이터 흐름을 이해하는 데 좋은 출발점입니다. 팝업뿐만 아니라 다른 하위 컴포넌트와의 통신에도 동일한 원리를 적용할 수 있으니, 프로젝트에 맞게 응용해보세요!
궁금한 점이 있으면 댓글로 남겨주세요. 다음 포스트에서 더 유용한 Vue.js 팁을 가져오겠습니다!
728x90
'Vue.js 를 배워보자' 카테고리의 다른 글
Vue.js와 Axios로 데이터셋을 그리드로 로딩하고 클릭 시 Input Text에 자동 바인딩하기 (0) | 2025.03.04 |
---|---|
Vue.js에서 JSON Server 포트 변경하기 (0) | 2025.03.02 |
import.meta와 import.meta.url로 모듈 메타데이터 활용하기 (0) | 2025.03.01 |
Vue.js와 Nuxt.js의 라우팅 이해: 정적 vs 동적 로딩과 디렉토리 기반 라우팅 (0) | 2025.02.23 |
Vue.js 컴포넌트 작성 스타일 비교: <script> + setup() vs <script setup> (0) | 2025.02.23 |