업무를 하면서

 

잘쓰던 컴포넌트가 있었다.

엄청 여러 화면에서 범용적으로 쓰는 컴포넌트 였다 

 

그런데 어떤! 특정한 화면! 에서만

비지니스적인 요구사항에 의해 특정 부분

예를들어 버튼이나. 문구 등을 바꾸고 싶었다 

 

그렇다고 문구나 명명 한두개만 바꾸면 되는데

굳이 새로운 컴포넌트를 만들어야 할까???

 

아니.

 

근데 또 기존 컴포넌트를 이용하고 싶은데

기존 이 컴포넌트는 가져다 쓰는 화면에서는 영향도가 없었으면 좋겠어!

 

이런 요구사항이 있었다..

 

정말 완벽하게 딱 맞는 개념이 있다

 

그거슨,,, 바로

 

Slot

 

 


1. Slot 이란?

컴포넌트의 재사용성을 높이기 위해서 사용하는 기능이다.

 

 

2. 예시

 

<navigation-link>

<a
  v-bind:href="url"
  class="nav-link"
>
  <slot></slot>
</a>

 

<navigation-link>의 부모 

<navigation-link url="/profile">
  Your Profile
</navigation-link>

 

 

이런식으로 해주면 <slot></slot> 의 부분에

Your Profile이란 글씨가 나오게된다.

 

3. 컴파일 범위

 

여기서 중요하게 알아야 할 것은,

컴파일 범위이다 (Compilation Scope)

 

<navigation-link url="/profile">
  Logged in as {{ user.name }}
  <!-- user는 부모 컴포넌트에서 있기때문에 잘 표시 될것이닷! --!>
</navigation-link>

 

<navigation-link url="/profile">
  Clicking here will send you to: {{ url }}
  <!--
  url은 undefined로 나올 겁니다. 이 데이터는 <navigation-link>로
  넘어가지만 <navigation-link> 컴포넌트 안에 정의되어 있지는
  않으니까요.
  -->
</navigation-link>

 

부모 템플릿 안에 있는 것들은 부모 컴포넌트의 범위에 컴파일되고 자식 템플릿 안에 있는 것들은 자식 컴포넌트의 범위에 컴파일됩니다.

 

 

 

4. default 값 지정

 

다음과 같이 <submit-button> 컴포넌트에는 slot을 지정해주는데 

default로 Submit이라고 지정해 주었다.

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

 

그래서 <submit-button>을 사용할때 따로 기입 하지 않으면 Submit이라고 나온다.

 

그런데 이렇게 Save 버튼을 만들고 싶으면 이렇게 만들어 주면 가능하다.

<submit-button>
  Save
</submit-button>

 

 

5. Named Slots

Vue 2.6.0 부터 지원

 

<base-layout> 컴포넌트다 여기 slot에는 각각 이름을 달아 주었다.

<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>

 

 

이렇게 이름있는 slot을 가져다 쓸때에는

다음과같이 template 해주고 v-slot:slot이름 을 넣어주면 된다.

<base-layout>
  <template v-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 v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>

 

다음도 가능 default 이름 넣어주기

 

<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>

 

 

6. Scoped Slots

자식 컴포넌트에서만 접근 할 수 있는 데이터에서 슬롯에 필요한 내용을 가져올때 필요하다.

 

 

다음은 불가하다.

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

 

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

부모에서 user에 접근 할 수 없다.

<current-user>만 user에 접근 할 수 있다.

 

 

그런데 user의 정보가 필요해 그렇다면?

 

 

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

 

 

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

 

다음과 같이 부모 컴포넌트에서 가져올 slotProps를 지정해주고 

자식 컴포넌트에서는 v-bind로 연결해주면 된다.

 

 

 

 

 

 

 

 


참고

https://kr.vuejs.org/v2/guide/components-slots.html

 

슬롯(Slots) — Vue.js

Vue.js - 프로그레시브 자바스크립트 프레임워크

kr.vuejs.org

 

 

+ Recent posts