Java Scripts/Vue.js

Vue : Scoped Slots - Part1

HobbyCoding 2022. 5. 15. 18:25
728x90

Slots allow developers to have the flexibility to provide content to a child component.

슬롯을 사용하면 개발자가 child component에 콘텐츠를 유연하게 제공할 수 있습니다.

but What happens when the child component has control of the data?

하지만 하위 구성 요소가 데이터를 제어하면 어떻게 되나요?

 

when we want to access data from the child, standard slots will not give us permission to grab that data.

하위 항목의 데이터에 액세스하려고 할 때 표준 슬롯은 해당 데이터를 가져올 수 있는 권한이 없다.

 

Book.vue

<template>
 <div class="book">
 <slot name="title"></slot>
 </div>
</template>
<script>
export default {
 data() {
 return {
 bookTitle: 'Child Providing Data'
 }
 }
}
</script>

Library.vue

<template>
 <Book>
 <template v-slot:title>
 <!-- How do we get the bookTitle from Book.vue? -->
 </template>
 </Book>
</template>

What are scoped slots?

Scoped slots is a technique for allowing a component to expose data to the slot’s template block.

Scoped slots은  component가 슬롯의 템플릿 블록에 데이터를 노출할 수 있도록 하는 기술입니다.

Slots allow us to put data into it from the parent.

슬롯을 사용하면 parent 에서  데이터를 child component 의 슬롯에 넣을 수 있습니다.

When we want to access data from the child, standard slots will not give us permission to grab that data. Hence, we need to expose the data from the child so that we can grab it and put it in the slot as desired.

하위 항목의 데이터에 액세스하려는 경우 표준 슬롯은 해당 데이터를 가져올 수 있는 권한을 부여하지 않습니다. 따라서 우리는 원하는 대로 데이터를 잡고 슬롯에 넣을 수 있도록 자식의 데이터를 노출해야 합니다.

 

Book.vue

<template>
  <div class="book">
    <slot name="title"></slot>
  </div>
</template>

<script>
export default {
  data() {
    return {
      bookTitle: 'Child Providing Data'
    }
  }
}
</script>

Library.vue

The data is currently embedded in our Book.vue component and we need to some how render it in the Library.vue component.

데이터는 현재 Book.vue 구성 요소에 포함되어 있으며 Library.vue 구성 요소에서 이를 렌더링하는 방법이 필요합니다.

<template>
  <Book>
    <template v-slot:title>
      <!-- How do we get the bookTitle from Book.vue? -->
    </template>
  </Book>
</template>

How do you use scoped slots?

LogoHeader.vue

Define a prop (like you would with a normal component) on our slot to expose our logoImage property to the slot.

슬롯에 prop(일반 구성 요소와 마찬가지로)을 정의하여 logoImage 속성을 슬롯에 노출합니다.

<template>
  <slot name="header" :logo="logoImage" />
</template>

 

<script>
export default {
  data() {
    return {
      logoImage: '/images/logo.png'
    }
  }
}
</script>

By defining these “slot props,” this allows us to access them in the <template> block by exposing the slotProps value.

이러한 "slot props,"을 정의하면 SlotProps 값을 노출하여 <template> 블록에서 해당 속성에 액세스할 수 있습니다.

 

App.vue

Once we expose the slot props, this allows us to use it within that <template> block.

slot props을 노출하면, 해당 <template> 블록 내에서 사용할 수 있습니다.

<template>
  <LogoHeader>
    <template v-slot:header="slotProps">
      {{ slotProps.logo }}
    </template>
  </LogoHeader>
</template>

 

Once Again for Reinforcement!

Using our Library.vue and Book.vue example , let’s implement the bookTitle property using scoped slots.

Library.vue 및 Book.vue 예제를 사용하여 범위가 지정된 슬롯을 사용하여 bookTitle 속성을 구현해 보겠습니다.

 

Step 1. Expose the data as props on the desired slots.

Book.vue

<template>
  <div class="book">
    <slot name="title" :bookTitle="bookTitle"></slot>
  </div>
</template>

<script>
export default {
  data() {
    return {
      bookTitle: 'Child Providing Data'
    }
  }
}
</script>

Step #2. Expose slot props on your <template> block

Library.vue

<template>
  <Book>
    <template v-slot:title="slotProps">
      <!-- How do we get the bookTitle from Book.vue? -->
    </template>
  </Book>
</template>

Step 3. Use slotProps to render out the desired data

Library.vue

<template>
  <Book>
    <template v-slot:title="slotProps">
      {{ slotProps.bookTitle }}
    </template>
  </Book>
</template>

 

아래는 모두 반영된 complete code 임

Book.vue

<template>
  <div class="book">
    <slot name="title" :bookTitle="bookTitle"></slot>
  </div>
</template>


<script>
export default {
  data() {
    return {
      bookTitle: 'Child Providing Data'
    }
  }
}
</script>

Library.vue

<template>
  <Book>
    <template v-slot:title="slotProps">
      {{ slotProps.bookTitle }}
    </template>
  </Book>
</template>