Vue

Vue(11) 자식이 부모데이터 바꾸고 싶으면 custom event 로 메세지만 주자

youngjae-kim 2024. 6. 10. 21:46
728x90
반응형

custom event

 

컴포넌트화 한 뒤 props로 받은 부모 데이터를

click event 같은걸로 부모 컴포넌트의 데이터를 변경하려고 하면 안된다고 했었다.

 

오늘은 그것을 가능하게 만들어보자.

 

Card.vue

<template>
    <div >
        <img :src="원룸.image" class="room__img" alt="">
        <h4 @click="모달창열렸니 = true; 누른거 = i">{{ 원룸.title }}</h4>
        <p>{{ 원룸.title }}</p> 
        <p>{{ 원룸.content }}</p> 
        <p>{{ 원룸.price }} 원</p>
    </div>
</template>

 

지금 '모달창열렸니', '누른거' 변수들을 수정을 하고 싶다.

 

다시 한번 정리를 하면 부모 컴포넌트로 받은 데이터들은 = 과 같은 걸로 수정을 하면 안된다.

부모로 받은 데이터를 그대로 사용만 하여야 한다. (read-only 이기 때문)

 

방법이 있기는 하다.

 

부모 컴포넌트에서 @click 이벤트를 부여하는 방법 -> 이벤트 버블링 발생 자식 컴포넌트 다른 태그에 까지 @click이벤트가 전파되는 현상

 

자식 컴포넌트에서 클릭 이벤트로 변경을 하기 위해서는 부모 컴포넌트에게 데이터를 변경해달라는 어떤 메시지 같은 것을 보내면 된다.

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

 

이렇게 @click 이벤트에 $emit('작명', 데이터)이라는 메서드를 사용한다.

데이터는 숫자, 문자, object 다 보낼 수 있다.

 

부모는 수신을 해야한다.

<!-- 상품 목록 시작 -->
  <Card @openModal="모달창열렸니=true" :원룸="원룸들[i]" v-for="(원룸,i) in 원룸들" :key="i"/>
  <!-- 상품 목록 끝 -->

 

수신할 때는 자식 컴포넌트에서 작명한 이름을 사용한다.

 

 

이렇게 데이터를 자식 컴포넌트에서 넘겨줄 수도 있다.

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

 

그럼 부모 컴포넌트에서 받을 때는

<Card @openModal="모달창열렸니 = true; 누른거 = $event" :원룸="원룸들[i]" v-for="(원룸, i) in 원룸들" :key="i" />

 

이렇게 $event를 사용해서 자식이 보낸 값을 받아서 사용할 수 있다.

 

 

함수로 빼서 다음과 같이 사용할 수 도 있다.

 

methods로 빼서 사용할거면 this를 붙여주자

 

Modal.vue

<template>
    <div class="black-bg" v-if="모달창열렸니 == true">
        <div class="white-bg">
            <img :src="원룸들[누른거].image" style="width:100%">
            <h4>{{ 원룸들[누른거].title }}</h4>
            <p>{{ 원룸들[누른거].content }}</p>
            <p>{{ 원룸들[누른거].price }} 원</p>
            <button @click="close">닫기</button>
        </div>
    </div>
</template>

<script>

export default {
    name: 'Modal',
    props: {
        원룸들: Object,
        누른거: Number,
        모달창열렸니: Boolean,
    },
    methods: {
        close() {
            this.$emit('closeModal')
        }
    }
}
</script>

<style scoped>

</style>

 

@click="close"로 지정하고 methods : { }에 $emit()을 선언

 

 

728x90
반응형