대가는 결과를 만든다

[Vue] slot 본문

개발/Vue

[Vue] slot

yunzema 2019. 4. 11. 11:31
반응형

Vue에는 slot이라는 개념이 있는데 무엇?

Parent Component에서 Child Component의 Element Tag사이에 삽입하여 Child Component의 원하는 Element로 fallback해주고자 할때 사용하는 개념이다.

 

 

1. Basic

<submit-button> Component를 다음과 같이 정의:

<button type="submit">
	<slot>Submit</slot>
</button>

 

그러면 <submit-button></submit-button>이라는 Component를 사용할 때,

<button type="submit"> Submit </button>

다음과 같이 렌더링이 될 것이다.

 

하지만 <submit-button> 전송 </submit-button> 과같이 Component를 사용하면

<button type="submit"> 전송 </button>

으로 렌더링이 된다. 

앞서 말한 것처럼 Tag사이에 넣은 값을 Child Component의 Slot으로 fallback되는 것이다.

 

 

2. Named Slot

*name을 정하지 않은 <slot>의 name은 "default"

 

<base-layout>이라는 Component를 다음과 같이 정의:

<div class="container">

<header> 
	<slot name="header"></slot>
</header>

<main>
	<slot></slot>
</main>

<footer>
	<slot name="footer"></slot>
</footer>

</div>

 

그리고 template tag와 v-slot으로 Child Component Slot을 매핑해서 사용한다면 아래와 같다.

<base-layout>

<template v-slot:header>
	<h1>Here might be a page title</h1>
</template>

<template v-slot:default>
	<p>A paragraph for the main content.</p>
    <p>And another one.</p>
</template>

<template v-slot:footer>
	<p>Here's some contact info</p>
</template>

</base-layout>

 

3. Scoped Slot

Parent Component에서 Child Component의 데이터를 이용하여 Slot을 변경하려는 경우에 사용되는 방법

 

<current-user>라는 Component가 다음과 같이 정의 하고, (* user는 Child Component에 속한 data) : 

<span>
	<slot>{{ user.lastName }}</slot>
</span>

 

Parent Component에서 다음과 같이 변경하려고 할때 되지 않는다. Parent에서는 Child의 user라는 data에 접근할 수 없기 때문이다.

<current-user> {{ user.firstName }} </current-user>

 

Parent에 user data에 접근할 수 있도록 하기 위해 slot의 attribute를 부여할 수 있다.

<span>
	<slot v-bind:user="user"> {{ user.lastName }} </slot>
</span>

 

<slot> Element에 binding된 Attribute를 "slot props"라고 하며 다음과 같이 v-slot을 이용해 Parent에서 접근할 수 있다.

<current-user>
	<template v-slot:default="slotProps"> {{ slotProps.user.firstName }} </template>
</current-user>

* 예시에서의 slotProps는 모든 slot props를 포함한 object의 naming을 임의로 정한 것으로 원하는 변수명으로 정의하면됨.

 

다음과 같이 줄여서 사용도 가능

<current-user v-slot:default="slotProps"> {{ slotProps.user.firstName }} </current-user>

하지만, multiple slot에는 각 template이 필요

<current-user>
	<template v-slot:default="slotProps"> {{ slotProps.user.firstName }} </template>
	<template v-slot:other="otherSlotProps"> ... </template>
</current-user>

 

* javascript 표현이 수용되므로 예시에서 사용한 "slotProps" 대신 다음과 같이 더 간단하게도 사용 가능

<current-user v-slot="{ user }"> {{ user.firstName }} </current-user>

 

Comments