minstudio

컴포넌트 심화: 슬롯(Slots)과 Provide/Inject

Props와 Emit만으로 모든 것을 해결하려다 보면 문제가 생깁니다. 부모가 자식의 내부 디자인(HTML)을 통째로 갈아 끼우고 싶거나, 할아버지 컴포넌트가 저 아래 까마득한 손자 컴포넌트에게 데이터를 주고 싶을 때는 어떻게 할까요? 이때 SlotsProvide/Inject가 등장합니다.

🧩 Slots & Provide/Inject 구조 1. 슬롯 (Slots) : 레이아웃 뚫어놓기 Modal.vue (자식) <slot name="header"> <slot name="footer"> 구멍(Slot)을 뚫어두면 부모가 HTML을 채워 넣음 2. Provide / Inject : 직통 데이터 App.vue (할아버지) Provide Layout.vue (아버지) Button.vue (손자) Inject Props 릴레이(Drilling) 없이 데이터를 직통 배송
<!-- ==========================================
// 📂 App.vue (Provide와 Slots 사용 예제)
// ========================================== -->
<script setup>
import { provide, ref } from 'vue';
import Modal from './Modal.vue';
import GrandChild from './GrandChild.vue';

// [1. Provide] 할아버지가 데이터를 제공합니다.
// 이 데이터는 자식, 손자, 증손자 등 하위 컴포넌트 어디서든 바로 꺼내 쓸 수 있습니다.
const themeColor = ref('dark');
provide('theme', themeColor); 
</script>

<template>
  <div class="p-8 bg-gray-50 max-w-lg mx-auto">
    <!-- 손자 컴포넌트를 그냥 불러옵니다. Props를 안 넘겨줘도 됩니다! -->
    <GrandChild />

    <!-- [2. Slots] 자식 컴포넌트의 구멍(slot)에 HTML 끼워넣기 -->
    <Modal>
      <!-- 자식 컴포넌트의 <slot name="header"> 위치에 들어갈 HTML -->
      <template #header>
        <h1 class="text-2xl text-red-600 font-bold">경고: 결제 실패</h1>
      </template>

      <!-- 자식 컴포넌트의 기본 <slot> 위치에 들어갈 HTML -->
      <p class="text-gray-700 my-4">잔액이 부족하여 결제가 취소되었습니다.</p>

      <!-- 자식 컴포넌트의 <slot name="footer"> 위치에 들어갈 HTML -->
      <template #footer>
        <button class="bg-gray-800 text-white px-4 py-2 rounded">닫기</button>
      </template>
    </Modal>
  </div>
</template>

<!-- ==========================================
// 📂 GrandChild.vue (Inject 예제)
// ========================================== -->
<script setup>
import { inject } from 'vue';

// 할아버지가 Provide로 뿌린 'theme' 이라는 데이터를 직통으로 꺼내옵니다.
// Props로 여러 번 전달받을 필요가 없습니다! (Prop Drilling 해결)
const theme = inject('theme');
</script>

<template>
  <div :class="theme === 'dark' ? 'bg-black text-white' : 'bg-white text-black'">
    현재 테마는 {{ theme }} 입니다!
  </div>
</template>
컴포넌트 심화: 슬롯(Slots)과 Provide/Inject | Minstudio