🖥️프론트엔드/Vue3
[Vue 3] Slot은 왜 사용하는가?
meteorfish
2025. 6. 18. 16:19
728x90
기존 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하기 위해선 아래와 같은 과정이 진행된다.
// 부모 컴포넌트
// Bank.vue
<Account :money="money" />
// 자식 컴포넌트
// Account.vue
<script>
export default {
name : 'Account',
props : {
money : String,
}
}
</script>
1. 부모 컴포넌트에서 커스텀 태그 및 v-bind를 통해 데이터 넘겨주기
2. 자식 컴포넌트에서 props로 바인딩된 데이터 가져오기
3. 자식 컴포넌트에서 사용하기 (위 코드에선 생략됨)
이 과정을 보다 편하게 사용할 수 있도록 Slot 태그를 사용할 수 있다.
BaseCard.vue
<template>
<div>
<slot></slot>
</div>
</template>
<style scoped>
div {
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);
padding: 1rem;
margin: 2rem auto;
max-width: 40rem;
}
</style>
div 태그를 가지는 컴포넌트로 재사용을 위해 전역 컴포넌트로 등록하여 사용하고 있다.
이 곳에 다양한 값들을 slot 태그를 통해 넣을 수 있다.
<template>
<li>
<base-card>
<header>
<h3>{{ title }}</h3>
<base-button mode="flat" @click="deleteResource(id)">Delete</base-button>
</header>
<p>{{ description }}</p>
<nav>
<a :href="link">View Resource</a>
</nav>
</base-card>
</li>
</template>
<script>
export default {
props: ['id', 'title', 'description', 'link'],
inject: ['deleteResource']
}
</script>
<style scoped>
// 생략
</style>
<base-card> 태그를 통해 BaseCard 컴포넌트의 slot 태그로 태그들을 넘길 수 있다.
이름이 있는 슬롯
만약 하나의 컴포넌트의 슬롯이 여러 개 있는 경우에는 이름을 부여하여 한다.
예를 들어 두 개의 슬롯이 있을 경우, 하나의 슬롯에만 이름을 부여하면 나머지 슬롯은 default라는 이름이 자동으로 부여된다.
BaseDialog
<template>
<teleport to="body">
<div @click="$emit('close')"></div>
<dialog open>
<header>
<slot name="header">
<h2>{{ title }}</h2>
</slot>
</header>
<section>
<slot></slot>
</section>
<menu>
<slot name="actions">
<base-button @click="$emit('close')">Close</base-button>
</slot>
</menu>
</dialog>
</teleport>
</template>
<script>
export default {
props: {
title: {
type: String,
required: true,
}
},
emits: ['close']
}
</script>
<style scoped>
// 생략
</style>
이 코드의 경우 header, actions, default 총 3개의 슬롯이 사용되고 있다.
<template>
<base-dialog v-if="inputIsInvalid" title="Invalid Input" @close="confirmError">
<template #default>
<p>Unfortunately, at least one input value is invalid.</p>
<p>Please check all inputs and make sure you enter at least a few character.</p>
</template>
<template #actions>
<base-button @click="confirmError">Okay</base-button>
</template>
</base-dialog>
<base-card>
<form @submit.prevent="submitData">
<div class="form-control">
<label for="title">Title</label>
<input id="title" name="title" type="text" ref="titleInput"/>
</div>
<div class="form-control">
<label for="description">Description</label>
<textarea id="description" name="description" rows="3" ref="descInput"></textarea>
</div>
<div class="form-control">
<label for="link">Link</label>
<input id="link" name="link" type="url" ref="linkInput"/>
</div>
<div>
<base-button type="submit">Add Resource</base-button>
</div>
</form>
</base-card>
</template>
base-dialog라는 태그 하위에 template 태그를 통해 slot을 지정할 수 있다.
`#슬롯이름` 으로 지정이 가능하다.
728x90