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 기초익히기 시리즈'
'Programming-[Frontend] > Vue.js' 카테고리의 다른 글
Vue.js / 기초 / 11. 서버 데이터 바인딩 하기 (w/postman Mock Server) (0) | 2021.07.23 |
---|---|
Vue.js / 기초 / 10. 라이프 사이클, Life cycle (0) | 2021.01.27 |
Vue.js / 기초 / 8. Emit으로 자식 -> 부모 컴포넌트에 데이터 보내기 (0) | 2021.01.26 |
Vue.js / 기초 / 7. props로 부모 -> 자식 컴포넌트에 데이터 보내기 (0) | 2021.01.26 |
Vue.js / 기초 / 6. 파일, 컴포넌트 및 router 구조 (2) | 2021.01.25 |