Props
props 는 쉽게 생각해서 부모가 자식에게 주는 데이터이다.
먼저 부모에게 물려받을 데이터를 자식 컴포넌트에 정의한다.
// Child.vue <script setup> const props = defineProps(['color']) </script> <template> <div :style="'border: 1px solid '+props.color"> 자식 컴포넌트 <div> 부모 데이터 : {{props.color}} </div> </div> </template>
부모가 준 color 값에 따라 자식 컴포넌트 div 의 color 가 변할 수있도록 div style에 color 값을 줬다.
이후 부모 컴포넌트에 자식 컴포넌트를 추가하여 color 값을 넘겨주었다.
// parent.vue <script setup> import Child from "@/views/Child.vue"; </script> <template > <div style="border: 1px solid blue;padding: 10px;width: 300px"> 부모 컴포넌트 <Child color="red" /> </div> </template>
이후 결과를 보면 자식 컴포넌트에 부모가 준 데이터가 잘 넘어간걸 볼 수 있다.
현재는 그냥 문자열로 넘겨줬지만 반응형 데이터로 넘겨주어도 자식 컴포넌트까지 변화가 된다.
color 를 반응형 변수로 선언하고 버튼 클릭시 color 값이 black으로 바뀌도록 하였다.
그리고 자식 컴포넌트에도 :color 로 하여 변수 값이 넘어가도록 수정하였다.
※ v-btn 은 현재 사용하는 vuetify tag 이다.
// parent.vue <script setup> import Child from "@/views/Child.vue"; import {ref} from "vue"; const color = ref('red') const changeColor = ()=>{ color.value = 'black' } </script> <template > <main class="pa-10"> <div style="border: 1px solid blue;padding: 10px;width: 300px"> 부모 컴포넌트 <Child :color="color" /> <v-btn color="primary" @click="changeColor">색 바꾸기 </v-btn> </div> </main> </template>
Emit – 부모 값 변경하기
이제 vue 를 하다보면 부모의 값을 변경하고 싶은 상황이 생긴다.
먼저 자식 컴포넌트에도 버튼을 만들어서 부모 값을 변경시켜보자.
// Child.vue <script setup> const props = defineProps(['color']) const changeProps = ()=>{ props.color = 'blue' } </script> <template> <div :style="'border: 1px solid '+props.color"> 자식 컴포넌트 <div> 부모 데이터 : {{props.color}} </div> <v-btn color="warning" @click="changeProps">부모값 변경하기</v-btn> </div> </template>
실행 결과 부모값은 변경되지 않는다.
Vue에서는 부모 컴포넌트가 준 props 값을 자식 컴포넌트에서 변경하지 못하게 되어있다.
그럼 어떻게 해야할까?
바로 이때 사용하는게 emit 이다.
자식 컴포넌트에는 emit = defineEmits([‘setColor’]) 을 추가해주고
emit(‘setColor’,’blue’) 이벤트를 준다.
// child.vue <script setup> const props = defineProps(['color']) const emit = defineEmits(['setColor']) // 추가 const changeProps = ()=>{ emit('setColor','blue') // 추가 } </script> <template> <div :style="'border: 1px solid '+props.color"> 자식 컴포넌트 <div> 부모 데이터 : {{props.color}} </div> <v-btn color="warning" @click="changeProps">부모값 변경하기</v-btn> </div> </template>
부모 컴포넌트는 자식 컴포넌트에 @setColor=”콜백함수” 을 추가해주고
콜백 함수에 prop으로 넘기던 color 값을 수정해준다.
// Parent.vue <script setup> import Child from "@/views/Child.vue"; import {ref} from "vue"; const color = ref('red') const changeColor = ()=>{ color.value = 'black' } // 추가 const setColor = (value)=>{ color.value = value } </script> <template > <main class="pa-10"> <div style="border: 1px solid blue;padding: 10px;width: 300px"> 부모 컴포넌트 <Child :color="color" @setColor="setColor" // 추가 /> <v-btn color="primary" @click="changeColor">색 바꾸기 </v-btn> </div> </main> </template>
요약하자면 자식이 부모의 함수를 콜백 해줌으로서 부모의 콜백 함수에서 부모의 값을 수정하는 것이지요.
직접적인 수정은 안되지만 부모의 함수를 콜백해서 부모가 직접 값을 변경하게 만드는 것입니다.
이렇게 emit 을 이용하여 부모값을 변경시킬수가 있습니다.