개발 도구 (Development Tools)/Vue

Vue 데이터를 전달하는 또 다른 방법 Slot

BiCute 2022. 9. 19. 08:00
반응형

 

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>

결과

 

 

Vue.js Slot > 

 

 

 

반응형