[Vue3] Composition API props와 emit 활용

겨울봄이·2023년 9월 19일
0
post-thumbnail

[Vue3] props와 emit 활용

Vue3 프로젝트 중에 props와 emit 개념이 정리되지 않아 게시글을 작성한다.

컴포넌트간의 데이터 교환이 필요할 때가 있는데, Vue에서는 props와 emit을 사용한다. 이해하기 편하게 밑에 부터는 부모와 자식으로 설명하겠다.

먼저 props를 소개한다.

Vue3의 Composition API와 <script setup>을 사용했다.

props는 부모Component 값을 자식Component에게 전달해줄때 사용한다.
아래 코드처럼 부모Component에서 자식Component를 import해서 사용한다.

부모Component에 전달할 props 값인 mainCont을 camelCase로 정한 경우에 DOM 템플릿 안에서는 kebab-case로 child-component와 같이 사용해야 올바르게 작동한다.
출처 : https://v2.ko.vuejs.org/v2/guide/components-props.html

ParentComponent Source

<!-- App.vue 부모 컴포넌트 -->
<script setup>
import ChildComponent from './ChildComponent.vue'

const post = {
  id: 1,
  title: 'hosb의 vue 활용',
  mainCont: 'props와 emit 사용 방법은 ~~',
}
  
const receive = (newValue: string) => {
  	// 수정한 값이 ChildComponent에서 값이 넘어옴
	console.log('newValue ::', newValue) 
	post.mainCont = newValue
}
</script>

<template>
  <child-component
    :title="post.title"
	:main-cont="post.mainCont"
	@update:main-cont="receive($event)"
  />
</template>

아래는 ChildComponent이다.

emit은 자식Component 값을 부모Component에게 전달할 때 사용한다.

ChildComponent 매핑 순서

  1. onMounted로 vo.value에 부모Component에서 받아온 props 값을 매핑한다.
  2. 그 후에 textarea 값이 @change를 감지하고 값이 변경되면 emit을 통해 부모Component에게 값을 전달한다.

    출처 : 본인 직접 작성


참고 : textarea의 변경된 값은 개발자도구(f12키)를 통해 console.log를 확인해볼 수 있다.

ChildComponent Source

<!-- ChildComponent.vue -->
<script setup>
import { onMounted, ref } from 'vue'
  
const props = defineProps(['title', 'mainCont']) // 부모Component에서 받은값
const emits = defineEmits(['update:mainCont'])
  
const vo = ref('')
  
onMounted(() => {
  vo.value = props.mainCont // vo에 받아온 props 값을 매핑함
})
</script>
  
<template>
  <h3> {{ props.title }} </h3>
  <textarea
    v-model="vo"
    @change="emits('update:mainCont', vo)"
  />
</template>

위의 소스는 Vue SFC Playground와 GitHub에 저장해두었으니 참고 부탁드립니다!

Vue SFC Playground Link
GitHub Link

props는 읽기전용이다.

참고로 아래와 같이 props는 읽기 전용으로 다시 쓰기를 못하게 막는다
다시 사용하는 방법도 있으나 권장하지 않는다.

const props = defineProps(['foo'])

// ❌ warning, props are readonly!
//   (경고, props는 읽기 전용입니다!)
props.foo = 'bar'

수정될 점이 발견되면 댓글 남겨주세요. 읽어주셔서 감사합니다!

출처 : https://ko.vuejs.org/guide/components/props.html#one-way-data-flow
출처 : https://ko.vuejs.org/guide/components/props.html

0개의 댓글