개발여행

Vue 배우기 (3) 본문

Frontend

Vue 배우기 (3)

jbilee 2024. 6. 6. 22:08

이벤트 emit

Vue에서는 자식 컴포넌트가 부모 컴포넌트에게 어떤 이벤트에 대한 시그널을 보내는 emit 기능을 활용할 수 있다.

 

자식 컴포넌트에 defineEmits()로 이벤트의 명칭을 선언하면, 부모 컴포넌트는 자식 컴포넌트를 렌더링할 때 v-on 디렉티브를 통해 해당 이벤트에 listen할 수 있다. v-on 디렉티브에 이벤트가 감지됐을 때 실행할 콜백을 전달하고, 그 콜백은 자동으로 자식 컴포넌트가 이벤트를 emit하면서 보낸 데이터를 인자로 받는다.

<!-- 자식 컴포넌트: emit할 이벤트 생성 -->
<script setup>
  const emit = defineEmits(["greet"])
  emit("greet", "hello, world")
</script>

<!-- 부모 컴포넌트: 이벤트 리스너 콜백 적용 -->
<template>
  <ChildComponent @greet="(msg) => console.log(msg)" />
</template>

 

이벤트 emit은 <script>가 아닌 <template>에서 DOM 태그 안에 직접적으로 넣는 것도 가능하다. 이벤트 핸들러 안에 $emit() 함수를 사용한다.

<!-- 자식 컴포넌트: <template> 안에서 $emit 사용 -->
<script setup>
  const emit = defineEmits(["greet"])
</script>

<template>
  <div @click="$emit('greet', 'hello, world')">Click me</div>
</template>

 

컴포넌트 prop

자식 컴포넌트가 prop을 받을 땐 defineProps()에 명시한다. 타입스크립트의 경우 defineProps() 안에다가 명시하는 대신 제네릭을 사용해야 한다. 이때 유의할 점은, defineProps() 안에 명시할 경우에는 기본 데이터 타입이 대문자로 시작해야 한다는 점이다.

<!-- 자바스크립트 -->
<script setup>
  const props = defineProps({
    myProp: String // 대문자로 시작해야 함
  })
</script>

<!-- 타입스크립트 -->
<script setup>
  const props = defineProps<{
    myProp: String
  }>()
</script>

 

슬롯

슬롯은 부모 컴포넌트가 자식 컴포넌트의 태그 안에 렌더링한 컨텐츠가 자식 컴포넌트 내 어느 위치에 렌더링할지 연결해주는 창구 역할을 하는 요소다. 자식 컴포넌트 template에 부모 컴포넌트로부터 내려받은 컨텐츠를 렌더링할 위치에 <slot> 태그를 넣어준다.

 

부모 컴포넌트가 자식 컴포넌트한테 아무것도 전달하지 않으면 슬롯이 위치한 자리에는 fallback 컨텐츠를 보여줄 수 있다.

<!-- 부모 컴포넌트: <ChildComponent> 안에 렌더링할 컨텐츠 전달 -->
<template>
  <ChildComponent>Parent's component</ChildComponent>
</template>

<!-- 자식 컴포넌트: 'Parent's component'가 <slot> 자리에 렌더링됨 -->
<template>
  <slot>Fallback content</slot>
</template>