자식 컴포넌트에서 부모 데이터를 사용하려면 보통 props로 전송해야 하는데, 번거로운 과정을 줄이기 위해 slot을 사용할 수 있습니다.
자식 컴포넌트
<slot></slot> 태그를 작성합니다.<!-- ChildComponent.vue -->
<template>
<div class="child-box">
<slot></slot>
</div>
</template>
<script setup>
// Vue3 <script setup> 구문 사용 (추가 로직이 있을 경우)
</script>
부모 컴포넌트
<slot> 자리에 자동으로 꽂힙니다.<!-- ParentComponent.vue -->
<template>
<ChildComponent>
부모에서 전달한 데이터 (slot의 내용)
</ChildComponent>
</template>
<script setup>
import ChildComponent from './ChildComponent.vue'
</script>
유의사항:
props는 src, style 등 HTML 속성에도 사용 가능하지만, slot은 HTML 태그이므로 HTML 태그처럼만 사용 가능합니다.
부모가 전달할 데이터가 여러 개일 때, 하나의 slot이 아닌 여러 slot을 사용하여 구분할 수 있습니다.
자식 컴포넌트
name 속성을 부여합니다.<!-- ChildComponent.vue -->
<template>
<div>
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot> <!-- 기본 slot -->
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
<script setup>
// 추가 로직이 필요한 경우 여기에 작성
</script>
부모 컴포넌트
<template v-slot:slotName> 대신 Vue3에서는 단축 구문인 <template #slotName>을 사용합니다.<!-- ParentComponent.vue -->
<template>
<ChildComponent>
<template #header>
헤더 데이터
</template>
기본 slot에 들어갈 데이터 (별도 template 없이 직접 작성 가능)
<template #footer>
푸터 데이터
</template>
</ChildComponent>
</template>
<script setup>
import ChildComponent from './ChildComponent.vue'
</script>
참고:
이름은 자유롭게 작명할 수 있으며, 기본 slot은 이름 없이도 사용 가능합니다.
경우에 따라 자식 컴포넌트가 가진 데이터를 부모로 전달해야 할 때 slot props를 사용할 수 있습니다.
자식 컴포넌트
<slot>에 자식 컴포넌트의 데이터를 바인딩하여 전달합니다.<!-- ChildComponent.vue -->
<template>
<div class="child-box">
<!-- 자식 데이터(childData)를 slot으로 전달 -->
<slot :childData="childData"></slot>
</div>
</template>
<script setup>
import { ref } from 'vue'
const childData = ref('자식에서 보낸 데이터')
</script>
부모 컴포넌트
<template #default="slotProps">와 같이 사용합니다.<!-- ParentComponent.vue -->
<template>
<ChildComponent>
<template #default="{ childData }">
<p>자식으로부터 받은 데이터: {{ childData }}</p>
</template>
</ChildComponent>
</template>
<script setup>
import ChildComponent from './ChildComponent.vue'
</script>
참고:
Slot props를 통해 자식의 데이터를 부모가 자유롭게 활용할 수 있습니다. (실제 사용 빈도는 많지 않지만, 상황에 따라 유용하게 사용할 수 있음)
<slot></slot><ChildComponent>내용</ChildComponent><slot name="a"></slot><template #a>데이터</template><slot :데이터="데이터"></slot><template #default="{ 데이터 }"> {{ 데이터 }} </template>
다른 블로그 봐도 모르겠던데 이 글 보고 slot 이해함! ㄳ