1. slot이 필요한 경우
아래의 샘플은 App.js 내부에 Box 컴포넌트가 하나 삽입되어 있는 형태입니다.
만일 Box 컴포넌트는 여기저기서 앞으로도 계속 써야 하는데, 지금 내가 필요한 건 Contents 1번 밑에 안내글 한 줄만 더 추가하고 싶은 경우.
다시 말하자면 데이터를 추가하고 싶은데 이전 모습 그대로의 컴포넌트를 계속 사용하고 싶다면, 원하는 위치에 구멍 <slot>을 뚫어 필요한 데이터를 전달할 수 있습니다
이 형태를 기본으로 slot을 사용해 보겠습니다.
(app.js)
<template>
<div> === APP.JS START === </div>
<Box />
<div> === APP.JS END === </div>
</template>
<script>
import Box from './components/Box.vue'
export default {
name: 'App',
components: {
Box
},
}
</script>
(box.vue)
<template>
<h1>Box Component</h1>
<p>Contents 1</p>
<p>Contents 2</p>
<p>Contents 3</p>
</template>
<script>
export default {
name: "BoxComponent",
}
</script>
2. slot의 기본적인 사용 방법
(1) 자식 컴포넌트의 원하는 위치에 구멍<slot>을 뚫어줍니다
(box.vue)
<template>
<h1>Box Component</h1>
<p>Contents 1</p>
<slot></slot> // <-- 원하는 위치에 구멍을 뚫어줍니다
<p>Contents 2</p>
<p>Contents 3</p>
</template>
(2) 부모 컴포넌트쪽에서 자식 컴포넌트를 불러온 태그 사이에 전송할 내용을 적어주면 끝입니다.
*축약형<Box />으로 불러왔다면 slot을 사용할 수 없으니 열고 닫는 태그로 변경해 줍니다.
(app.vue)
<template>
<div> === APP.JS START === </div>
<Box>구멍에 들어갈 내용</Box>
<div> === APP.JS END === </div>
</template>
3. slot이 여러개일 경우
(1) 자식 컴포넌트의 slot에 name값을 지정해 줍니다.
(Box.vue)
<template>
<h1>Box Component</h1>
<p>Contents 1</p>
<slot name="first"></slot> // <-- slot에 원하는 이름으로 name 값을 지정해 줍니다.
<p>Contents 2</p>
<slot name="second"></slot> // <-- slot에 원하는 이름으로 name 값을 지정해 줍니다.
<p>Contents 3</p>
</template>
(2) 자식 컴포넌트 사이에 <template v-slot:작명한 name> 형식으로 태그를 생성한 후 내부에 전송할 내용을 작성합니다
(App.js)
<template>
<div> === APP.JS START === </div>
<Box>
<template v-slot:first>구명1에 들어갈 내용</template>
<template v-slot:second>구멍2에 들어갈 내용</template>
</Box>
<div> === APP.JS END === </div>
</template>
참고
slot으로 전송하는 내용은 문자 뿐만이 아니라 태그(<span> 등)도 함께 작성해서 보낼 수 있으며,
굳이 props를 전달하는 과정을 거치지 않아도 {{ 데이터 값 }} 같은 데이터 형식으로도 전달할 수 있습니다.
단, 슬롯은 <div>같은 태그 내부에서만 데이터 바인딩이 되며, 속성 값에 slot을 뚫어서 사용할 수는 없기에 props와는 큰 차이점이 있습니다.
4. 자식의 데이터를 부모가 가져다 쓰는 또다른 방법 - slot props
(1) 자식 컴포넌트에서 slot 태그 내부에 기존 props 전송하듯 전송할 내용을 작성해 줍니다.
(Box.vue)
<template>
<h1>Box Component</h1>
<p>Contents 1</p>
<slot :user="user"></slot> // <-- user라는 이름으로 user의 데이터를 전송
<p>Contents 2</p>
<p>Contents 3</p>
</template>
<script>
export default {
name: "BoxComponent",
data(){
return{
user: 'BiCute', // <-- Object 형식의 데이터 추가
}
}
}
</script>
(2) 부모 컴포넌트에서 <template v-slot="작명">형태로 작성한 후,
태그 내부에 {{ 작명 }} 형식으로 가져온 데이터를 사용할 수 있습니다.
*아래는 오브젝트 형식의 데이터를 가져왔기 때문에 원하는 이름을 출력하기위해선 .user가 필요합니다.
(App.vue)
<template>
<div> === APP.JS START === </div>
<Box>
<template v-slot="slotProps"> <p>내 이름은 {{ slotProps.user }} 탐정이죠.</p></template>
</Box>
<div> === APP.JS END === </div>
</template>