이번엔 모달창의 [닫기]버튼을 작동하게 만들것입니다.
모달창(자식 컴포넌트)에서아래와 같이 입력하면 동작을 하지 않습니다.
<button @click="ModalPopup = false" class="closeButton">닫기</button>
애초에 ModalPopup은 부모 컴포넌트에 있고, props로 내려받은 값이라도 자식이 부모의 것을 함부로 바꾸는것은 허용되지 않습니다.
자식 컴포넌트에서 부모 컴포넌트의 데이터를 수정하기 위해선 자식은 부모에게 "***를 어떻게 해주세요" 라고 부탁들 해야합니다. (현실이 반영되어있네요....)
1. 커스텀 이벤트
Vue에서는 부모 컴포넌트의 데이터를 수정하고 싶을때 ~~ 주세요 라고 요청하는것을 커스텀 이벤트라고 부릅니다.
커스텀 이벤트는 다음과 같은 순서로 작성합니다.
(1) 자식 컴포넌트는 $emit('작명', 부모에게전달해줄값) 형태로 부모에게 요청합니다.
(2) 부모 컴포넌트는 @작명 = "실행할 자바스크립트 코드" 형식으로 작성을 합니다.
위 내용을 실제로 만들던 곳에 적용시켜보면 다음과 같습니다.
// ModalPopup.vue (자식 컴포넌트)
<button @click="$emit('ModalClose')" class="closeButton">닫기</button>
// App.vue (부모 컴포넌트)
<ModalPopup @ModalClose="ModalPopup = false" :post="post" :selectPost="selectPost" v-if="ModalPopup" />
자식 요소에서 닫기 버튼을 클릭(@click)하면 자식은 부모에게 'ModalClose' 해줘~~ 라고 요청을 하게 됩니다.
부모는 자식이 ModalClose 해달라고 요청하면(@ModalClose) 어떻게 해줄것인지(ModalPopup = false) 미리준비하고 있기 때문에 그 행동을 실행합니다.
※ 실행할 자바스크립 코트가 인라인 스타일일 필요는 없습니다. 긴 명령어는 methods에 정의해놓은후 그 함수를 실행하면 됩니다.
2. 부모에게 데이터를 전달해주는 예
위에서는 간단한 명령만 부탁하면 되는거였기에 emit의 2번째 인수는 사용하지 않았는데, 값을 전달하고 확인하는 방법은 다음과 같습니다.
// ModalPopup.vue (자식 컴포넌트)
<template>
<div class="popup">
<h2 class="popupTitle">제목: {{ post[selectPost].title }}</h2>
<p class="popupDate">작성일: {{ post[selectPost].date }}</p>
<p class="popupContents">내용: {{ post[selectPost].contents }}</p>
<button @click="$emit('ModalClose', post[selectPost] )" class="closeButton">닫기</button>
</div>
</template>
자식 컴포넌트가 ModalColse라는 이름으로 요청을 보내면서 post[인덱스번호]라는 값을 전달하고있습니다.
// App.vue (부모 컴포넌트)
<ModalPopup @ModalClose="modalColse(data)" :post="post" :selectPost="selectPost" v-if="ModalPopup" />
methods: {
modalClose(data){
this.ModalPopup = false
console.log(data)
}
}
전달받은 값은 data로 받아오기 때문에 console.log로 해당값을 출력해보면 어떠한 데이터가 들어왔는지 확인 할 수 있습니다.
오브젝트 형식으로 받았다면 data.id, data.name 등의 방식으로 원하는 부분을 꺼내서 쓰면 됩니다.