티스토리 뷰
1. Slot Content
<navigation-link url="/profile">
Your Profile
</navigation-link>
부모 컴포넌트에서 자식 컴포넌트를 위의 코드와 같이 사용하여 자식 컴포넌트의 하위 엘리먼트의 값들을 보여주고 싶다면,
<a
v-bind:href="url"
class="nav-link"
>
<slot></slot>
</a>
위의 코드와 같이 자식 컴포넌트가 작성되어야 합니다. 위의 코드들이 랜더링 되면 <slot>
엘리먼트는 Your Profile
이라는 문구로 대체됩니다. <slot>
은 문자열 뿐만 아니라 모든 HTML과 대체 될 수 있습니다.
<navigation-link url="/profile">
<!-- Add a Font Awesome icon -->
<span class="fa fa-user"></span>
Your Profile
</navigation-link>
위의 코드와 같은 기본 HTML 태그 뿐만 아니라,
<navigation-link url="/profile">
<!-- Use a component to add an icon -->
<font-awesome-icon name="user"></font-awesome-icon>
Your Profile
</navigation-link>
위의 코드와 같은 사용자 정의 컴포넌트도 <slot>
과 대체 될 수 있습니다. 자식 컴포넌트에서 <slot>
을 사용하지 않았다면, 부모 컴포넌트에서 자식 컴포넌트의 하위 엘리먼트로 넘겨 준 값들은 모두 무시 됩니다.
2. Named Slots
부모 컴포넌트에서 자식 컴포넌트로 여러개의 하위 엘리먼트를 넘겨줄 때 이름이 있는 <slot>
을 사용한다면 특정 위치를 지정할 수 있습니다.
<div class="container">
<header>
<!-- We want header content here -->
</header>
<main>
<!-- We want main content here -->
</main>
<footer>
<!-- We want footer content here -->
</footer>
</div>
예를 들면, 위의 코드와 같이 <base-layout>
이라는 컴포넌트가 있습니다. 하당 컴포넌트에는 <header>
와 <main>
, <footer>
3개의 정보가 채워져야 합니다.
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
이 경우에 위의 코드와 같이 이름이 있는 <slot>
을 사용할 수 있습니다.
<base-layout>
<template slot="header">
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template slot="footer">
<p>Here's some contact info</p>
</template>
</base-layout>
부모 컴포넌트에서는 자식 컴포넌트인 <base-loyout>
컴포넌트를 위의 코드와 같이 사용할 수 있습니다.
<base-layout>
<h1 slot="header">Here might be a page title</h1>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<p slot="footer">Here's some contact info</p>
</base-layout>
위의 코드와 같이 <template>
를 사용하지 않고 직접 엘리먼트에 slot 속성을 사용할 수도 있습니다. 이름이 없는 기본 <slot>
은 항상 하나만 존재해야 합니다.
<div class="container">
<header>
<h1>Here might be a page title</h1>
</header>
<main>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</main>
<footer>
<p>Here's some contact info</p>
</footer>
</div>
<base-layout>
컴포넌트 예제는 결국 위의 코드와 같이 랜더링됩니다.
3. Default Slot Content
slot
은 기본값을 제공합니다.
<button type="submit">
<slot>Submit</slot>
</button>
위의 코드와 같이 <submit-button>
컴포넌트가 있을 때, <submit-button>
컴포넌트의 하위 엘리먼트가 제공되지 않는다면, 기본값으로 Submit
이 화면에 보이게 됩니다. <submit-button>
컴포넌트의 하위 엘리먼트가 존재한다면, Submit
이 아닌 <submit-button>
컴포넌트의 하위 엘리먼트가 화면에 나타나게 됩니다.
4. Compilation Scope
slot
에 data를 사용하고 싶을 때,
<navigation-link url="/profile">
Logged in as {{ user.name }}
</navigation-link>
위의 코드와 같이 사용할 수 있습니다. 이 때 사용한 user.name
은 <navigation-link>
컴포넌트의 스코프에 있는 값이 아닌, <navigation-link>
컴포넌트를 사용한 부모 컴포넌트의 스코프에 있는 값입니다.
5. Scoped Slots
이 기능은 2.1.0 이상의 Vue 버전에서 제공하는 기능입니다.
slot
을 사용할 때 하위 컴포넌트의 데이터를 부모 컴포넌트에서 사용해야 할 때가 있습니다. 예를 들어,
<ul>
<li
v-for="todo in todos"
v-bind:key="todo.id"
>
{{ todo.text }}
</li>
</ul>
위의 코드와 같이 <todo-list>
라는 컴포넌트가 있을 때, 위의 컴포넌트는 <toto-list>
컴포넌트 스코프 안에 있는 todos
의 값을 나타냅니다. 부모 컴포넌트에서 자식 컴포넌트의 data를 사용하기 위해서는,
<ul>
<li
v-for="todo in todos"
v-bind:key="todo.id"
>
<!-- We have a slot for each todo, passing it the -->
<!-- `todo` object as a slot prop. -->
<slot v-bind:todo="todo">
<!-- Fallback content -->
{{ todo.text }}
</slot>
</li>
</ul>
자식 컴포넌트인 <todo-list>
컴포넌트에서는 위의 코드와 같이 작성되어야 합니다.
<todo-list v-bind:todos="todos">
<!-- Define `slotProps` as the name of our slot scope -->
<template slot-scope="slotProps">
<!-- Define a custom template for todo items, using -->
<!-- `slotProps` to customize each todo. -->
<span v-if="slotProps.todo.isComplete">✓</span>
{{ slotProps.todo.text }}
</template>
</todo-list>
부모 컴포넌트에서는 위의 코드와 같이 작성하여 자식 컴포넌트의 data를 사용할 수 있습니다. 이 때 slot-scope
는 <template>
에서 사용 되었지만 2.5.0 이상의 버전에서는 일반 엘리먼트에서도 사용 가능해 졌습니다.
1) Destructuring slot-scope
slot-scope
에 구조분해 문법 사용이 가능합니다.
<todo-list v-bind:todos="todos">
<template slot-scope="{ todo }">
<span v-if="todo.isComplete">✓</span>
{{ todo.text }}
</template>
</todo-list>
위의 코드와 같이 구조분해 문법을 사용하면 좀 더 간결한 코드가 될 수 있습니다.
참고
'Vue.JS' 카테고리의 다른 글
[Vue.JS] 컴포넌트 (고급:Handling Edge Cases) (0) | 2019.02.02 |
---|---|
[Vue.JS] 컴포넌트 (고급:Dynamic & Async Components) (0) | 2019.01.29 |
[Vue.JS] 컴포넌트 (고급:Custrom Events) (0) | 2019.01.24 |
[Vue.JS] 컴포넌트 (고급:props) (2) | 2019.01.21 |
[Vue.JS] 컴포넌트 (기본) (3) | 2019.01.16 |