Language/Vue.js

[Vue] 자식이 부모데이터 바꾸고 싶을 때 custom event

JJcoding 2024. 5. 5. 15:45

지난 시간에 props로 받아온 데이터를 자식 컴포넌트에서 수정할 수 없어서 모달창을 열 수가 없었다. 이것을 해결해보자!

가장 쉬운 해결 방법은? 그냥 컴포넌트에 이벤트를 주는 것이다.

<Card @click="modalOpen=true; 누름=i" :원룸="원룸들[i]" v-for="(원룸,i) in 원룸들" :key="원룸" />

--> 그런데 이렇게 하면 제목을 누르든, 이미지를 누르든, 가격을 누르든 모두 모달창이 열리게 된다. (이벤트 버블링 현상에 의해)

 

나는 제목을 클릭했을 경우에만 모달창이 열리게 하고 싶다. 그렇다면?

custom event 를 사용한다.

부모 컴포넌트에게 몇 가지 정보와 함께 데이터를 수정해달라는 메세지를 보낸다고 생각하면 된다. 

<template>
    <div>
    <img :src="원룸.image" class="room-img">
    <h4 @click="$emit('작명',데이터)">{{ 원룸.title }}</h4>
    <p>{{ 원룸.price }}원</p>
  </div>
</template>

--> $어쩌구는 Vue 만의 특별한 변수이다. 부모에게 메세지를 보낼 땐 $emit 함수를 사용하면 된다.

<template>
    <div>
    <img :src="원룸.image" class="room-img">
    <h4 @click="$emit('modalOpen')">{{ 원룸.title }}</h4>
    <p>{{ 원룸.price }}원</p>
  </div>
</template>

--> 부모에게 메세지를 발사한다. 데이터는 보내고 싶지 않으면 보내지 않아도 된다.

그러면 부모 컴포넌트에서는 이벤트를 수신하는 코드를 작성한다.

<Card @modalOpen="modalOpen = true" :원룸="원룸들[i]" v-for="(원룸,i) in 원룸들" :key="원룸" />

--> @modalOpen이라는 메세지를 받으면 modalOpen=true가 되도록 설정한다.

 

근데 여기서 문제! 같은 모달창이 계속 뜨게 된다. 이유는? 어떤(몇번째) 데이터인지 확인되지 않았기 때문이다.

그래서 자식 컴포넌트에서 부모에게 메세지를 보낼 때 몇 번째 데이터인지에 대한 정보도 함께 보내준다.

<h4 @click="$emit('modalOpen', 원룸.id)">{{ 원룸.title }}</h4>

--> 원룸.id 는 oneroom.js에 담겨있던 데이터이다. 숫자로 0~5까지 있다.

부모 컴포넌트는 데이터를 수신한다.

 <Card @modalOpen="modalOpen = true; 누름= $event" :원룸="원룸들[i]" v-for="(원룸,i) in 원룸들" :key="원룸" />

--> $event 는 자식 컴포넌트에서 보낸 데이터를 수신한다는 의미이다. 이렇게 하면 누름 = 0, 누름 = 1 이런식으로 해당 id가 들어가게 된다.

 

그러면 기존과 마찬가지로 모달창이 해당 데이터에 맞게 잘 뜨게 된다.

 

$emit 메세지가 너무 길다면 함수로 뽑아서 사용해도 된다.

export default {
    name: 'Card_',
    props: {
        원룸 : Object,
    },
    methods: {
        send() {
            this.$emit('modalOpen', this.원룸.id)
        }
    },
}

--> 이렇게 밑에서 함수를 생성하고 (this 필수)

<template>
    <div>
    <img :src="원룸.image" class="room-img">
    <h4 @click="send">{{ 원룸.title }}</h4>
    <p>{{ 원룸.price }}원</p>
  </div>
</template>

--> 함수 이름만 적어주면 끝!

 

출처 : 코딩애플