- slot

특정 컴포넌트에 등록된 하위 컴포넌트의 마크업을 확장하거나 재정의하여 재사용성을 높여주는 기능 입니다.

예를 들어 모든 페이지에서 범용성 있게 사용하는 컴포넌트에 간단한 추가적인 레이아웃을 구현해야 한다고 생각해 봅시다.

이미 사용중인 다른 페이지의 영향을 안받도록 구현해야할 뿐만 아니라 노출에 대한 분기처리를 해주어야 합니다.

v-slot을 사용할 경우 새로운 컴포넌트를 추가하지 않아도 기존의 컴포넌트를 확장하여 사용할 수 있습니다.

 

 

 

Vue.js 2.6.0이상 에서

named slot과 scoped slots 의 문법적 사용이 변경되었습니다. 따라서 설명은 최신 문법 기준으로 설명하겠습니다.

 

named Slot

                  <변경 전>                                                                                          <변경 후>   

<base-layout>                                                                                <base-layout>
    <template slot="header">                                                              <template v-slot:header> 
        <h1>Here might be a page title</h1>.                                              <h1>Here might be a page title</h1>
    </template>                                                                                      </template>
</base-layout>                                                                              </base-layout>

 

 

scoped slots

                  <변경 전>                                                                                         <변경 후>

<slot-example>                                                                         <slot-example>  
    <template slot="default" slot-scope="slotProps">               <template v-slot:default="slotProps" >
        {{ slotProps.msg }}                                                                     {{ slotProps.msg }}
    </template>                                                                                </template>
</slot-example>                                                                        </slot-example>

 

 

 

 

상위 컴포넌트

<template>
  <div class="app">
    <ChildComponent>
    
    <!-- default는 이름이 지어 지지않은 slot에 기본 값으로 적용 됩니다. -->
      <template v-slot:default>
        <span>안녕하세요</span>
      </template>
      
    </ChildComponent>
  </div>
</template>

하위 컴포넌트

<template>
  <div class="child-component">
    <slot></slot>  <!-- 해당 태그가 교체 됩니다. --> 
  </div>
</template>

 

결과

<template>
  <div class="child-component">
    <span>안녕하세요</span> 
  </div>
</template>

랜더링 시 <slot><slot> 태그는 상위 컴포넌트 하위 컴포넌트 태그 안의 값 <span>안녕하세요</span> 으로 치환됩니다. 

 

 

 

 

하나의 슬롯을 이용하는 것 말고 여러개의 슬롯을 특정 위치에 배치하고 싶다면 어떻게 할까요?

 

Named Slots

slot 마다의 이름을 지정해 준다면 원하는 위치에 해당 태그들을 대치 시킬 수 있습니다.

v-slot:[name] 또는 #[name]

하위 컴포넌트에서 아무 이름을 입력해 주지 않는다면 default 태그로 인식됩니다.

허나 default 이름을 가진 slot 태그와 아무 이름도 갖지 않은 slot태그가 동시에 존재한다면 default에 대치되게 됩니다.

 

 

상위 컴포넌트

<template>
  <div class="app">
  
    <ChildComponent>
    
      <template v-slot:apple>
        <span>apple</span>
      </template>

      <template v-slot:default>
        <span>기본값 이름입니다.</span>
      </template>
      
    </ChildComponent>
    
  </div>
</template>

하위컴포넌트

<template>
  <div class="child-component">

    <!-- v-slot:apple은 이곳에 대치 됩니다. -->
    <slot name="apple"></slot>

    <!-- v-slot:default는 이곳에 대치 됩니다.-->
    <slot></slot>
    
  </div>
</template>

결과

 

 

 

 

 

Scoped Slots

상위 컴포넌트에서 하위 컴포넌트의 값이 필요할 경우가 생긴다면 어떻게 될까요? 

 

하위 컴포넌트 

하위 컴포넌트에서 보내고자 하는 apple 과 func1을 slot 태그내에 v-bind 해주면 됩니다.

 

상위 컴포넌트

 

 

하위 컴포넌트에서 v-bind로 던저준 값을 상위 컴포넌트에서 구조분해 할당을 통해 가져올 수 있게 됩니다! 

 

 

 

v-slot을 알게 되면 여러모로 코드를 볼때 편해지게 됩니다. vutify의 dialog와 bootstrapVue의 tag등 편하게 사용하려쓰는

디자인 라이브러리 내에서도 v-slot을 많이 이용하고 있기 때문입니다. 

 

 

언제나 추가적인 질문 및 잘못된 내용을 알려주세요!

더 많은 공부가 될 수 있는 기회가 되었으면 좋겠습니다!

'FE > Vue' 카테고리의 다른 글

[vue.js] Vuex를 통한 상태 관리 패턴  (0) 2021.07.04

+ Recent posts