본문 바로가기
관리자

Programming-[Frontend]/Vue.js

Vue.js / 기초 / 9. Slot의 필요성과 사용 방법

728x90
반응형

 

1. Slot의 필요성

Slot은 자식(하위) 컴포넌트를 그대로 유지하면서 다른 부모(상위) 컴포넌트들마다 다른 내용을 적용하고 싶을 때 사용한다. 기본적으로는 부모 컴포넌트의 요소를 자식 컴포넌트에 내려받는 방식으로 사용한다. 아래와 같이 About.vue라는 상위 요소 컴포넌트에 하위 요소로 Header.vue 컴포넌트가 있는 경우를 생각해보자.

 

이 상황에서 first, second, third의 윗 부분에 요소를 추가하고 싶다면? 하위 컴포넌트인 Header.vue에 요소를 직접 추가하면 된다. 하지만 Header.vue 컴포넌트는 다른 컴포넌트에서도 그대로 사용하고 싶은 상황이라면 slot을 사용하는 것이 유리하다. 아래와 같이 Slot을 이용하여 각 영역에 Here is... 구문을 추가하는 방법을 배워보자.


2. Slot 사용 방법 및 문법

아래와 같은 코드로 Slot을 사용할 수 있게 된다. 

 

[상위 컴포넌트]

상위 컴포넌트에 들어간 하위 컴포넌트를 < Header /> 로 쓰는 것이 아니라 열고 닫는( <Header> </Header>) 구조로 작성해주고, 그 사이 부분에 template 태그를 추가한다.

 

그리고 각 template 태그에 v-slot: 또는 # 기호를 달아주어, 하위 컴포넌트에서 지정할 slot 요소의 이름을 지정해준다. 맨 마지막 이름이 없는 template는 하위 컴포넌트에서 default slot 값으로 처리되는데, 다음 [하위 컴포넌트] 부분에서 확인할 수 있다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template>
  <div>
    <h1>About page</h1>
    <Header>      
      <template v-slot:forFirst>
        <p>Here is the first</p>
      </template>
      <template #forSecond>
        <p>Here is the second</p>
      </template>
      <template #default>
        <p>Here is the third</p>
      </template>
    </Header>    
  </div>
</template>
cs

 

[하위 컴포넌트]

하위 컴포넌트의 template 요소에 <slot> 요소를 추가한다. 상위 컴포넌트에서 v-slot 등으로 지정한 값이 slot 태그의 name 속성의 값이 되도록 하면 <slot> 요소들이 기존의 하위 컴포넌트 요소들과 함께 표기되게 되는 것이다. 하위 컴포넌트에서 이름을 지정해주지 않은 무기명의 slot은 상위 요소에서의 #default 요소에 대응되어 적용된다.

 

1
2
3
4
5
6
7
8
9
10
11
<template>
  <div>  
    <slot name = "forFirst"></slot>
    <p> first</p>      
    <slot name = "forSecond"></slot>
    <p> second </p>
    <slot></slot>
    <p> third </p>      
  <br>
  </div>
</template>
cs

 

 


 

3. slot에 데이터 넣기

slot을 활용하면 위의 내용과 같이 상위 컴포넌트에서 추가를 원하는 요소와 하위 컴포넌트를 함께 사용할 수 있을 뿐만 아니라, 하위 컴포넌트의 데이터를 slot 부분에 넣어서 상위 컴포넌트에서 출력되게 할 수도 있다.

 

[하위 컴포넌트]

하위 컴포넌트의 forFirst slot에 fromHeader라는 속성을 만들어주고, data.title 값을 v-bind(:) 해주었다. 이제 상위 컴포넌트에 이 fromHeader 속성을 추가해주면 하위 컴포넌트의 title 데이터를 상위 컴포넌트에 추가할 수 있게 된다.

(혹시 기존에 props : { title : {... } }로 작성한 부분이 있다면 삭제 후 진행하자)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template>
  <div>  
    <slot name= "forFirst" :fromHeader="title"></slot>
    <p> first</p>      
    <slot name= "forSecond"></slot>
    <p> second </p>
    <slot></slot>
    <p> third </p>      
  <br>
  </div>
</template>
<script>
export default {
  data() {
    return {
      title : 'Vue.js study~'
    }
  },
cs

 

[상위 컴포넌트]

상위 컴포넌트에서 v-slot으로 지정된 부분의 값을 "props"로 지정하였다. props가 아니라 어떤 이름이라도 상관없다. 단지 속성의 이름일 뿐이다.

 

그리고 나서 props.fromHeader로 하위 컴포넌트에서 올려준 데이터를 받아와서 콧수염 문법( {{ }} )으로 처리하였다. 결과 화면은 아래와 같다.

 

추가로, v-slot:forFirst = { fromHeader } , {{ fromHeader }} 라고 작성하여 객체분해할당 문법을 활용하면 조금 더 깔끔한 문법이 될 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template>
  <div>
    <h1>About page</h1>
    <Header>      
      <template v-slot:forFirst="props">
        <p>Here is the first {{props.fromHeader}} </p>
      </template>
      <template #forSecond>
        <p>Here is the second</p>
      </template>
      <template >
        <p>Here is the third</p>
      </template>
    </Header>
  </div>
</template>
cs

 


참조

 

1) 유튜브 코지코더 - '뷰js 2 기초익히기 시리즈'

www.youtube.com/channel/UCI4tTBupvhMX1aWDSm-HAXw

728x90
반응형