Vue Advanced Components

해결하는 문제

적용 맥락

Vue Component Architecture와의 관계

Vue Component Architecture의 data input, behavior output, content input contract를 실제 API로 설계하는 pattern이다.

Props·Emit·Slot으로 contract 설계하기

1. Props로 read-only data input을 정의한다

2. Emit으로 interaction과 payload를 알린다

3. Slot으로 content와 layout variation을 연다

언제 Props/Emit/Slot을 쓸까

요구 사용할 contract 이유
Child가 읽어야 하는 data Props Data ownership과 방향이 명확하다.
Child에서 발생한 사용자 의도 Emit Parent가 state 변경을 승인한다.
Parent가 제공할 markup/content Slot Child skeleton과 parent content를 분리한다.
Child data를 parent markup에서 rendering Scoped slot Child가 slot props로 필요한 범위만 노출한다.

Reusable API를 소유권 기준으로 평가하기

Reusable component API는 "몇 개의 option을 제공하는가"보다 "누가 data를 소유하고 누가 rendering을 결정하는가"로 평가한다고 볼 수 있다. Props/Emit/Slots를 한 component에서 함께 사용할 수 있지만, 각 contract의 방향을 섞지 않는다. Project-specific vue-board 구현은 보존 대상 지식이 아니라 이 contract가 form/list component에 적용되는 검증 사례로만 사용한다.

예시

<!-- DataTable.vue -->
<script setup>
defineProps({ rows: Array })
const emit = defineEmits(['select'])
</script>

<template>
  <table>
    <tbody>
      <tr v-for="row in rows" :key="row.id" @click="emit('select', { id: row.id })">
        <slot name="row" :row="row">
          <td>{{ row.name }}</td>
        </slot>
      </tr>
    </tbody>
  </table>
</template>

관련

출처

테스트 질문


  1. 04.Vuejs-Component심화.pdf — Props를 read-only data로 설명(p.8), defineEmits()로 event 선언과 "여러 값을 전달해야 하는 경우, 각 인자를 따로 보내기보다는 하나의 객체로 묶어 전달하면 부모 컴포넌트에서 관리하기 쉬움"(p.17), Props/Slots 구분(p.22), slot props로 child data 노출(p.28) ↩︎ ↩︎ ↩︎ ↩︎