loading

Vue Scoped Slots

Local data from the component is provided by a scoped slot, allowing the parent to select how to present it.

Send Data to Parent

To transfer local data to the parent, we utilize v-bind in the component slot:

SlotComp.vue:

				
					<template>
  <slot v-bind:lclData="data"></slot>
</template>

<script>
  export default {
    data() {
      return {
        data: 'This is local data'
      }
    }
  }
</script>
				
			

Since it cannot be seen by the parent unless it is sent up to the parent, as we are doing here with v-bind, the data inside the component can be referred to as “local.”

Receive Data from Scoped Slot

Local data in the component can be received in the parent using v-slot and is sent using v-bind:

Example

App.vue:

				
					<slot-comp v-slot:"dataFromSlot">
  <h2>{{ dataFromSlot.lclData }}</h2>
</slot-comp>
				
			

As we can see, in the preceding example, ‘dataFromSlot’ is only a name we might give to the data object we get from the scoped slot. We get the text string from the slot by utilizing the ‘lclData’ property, and we utilize interpolation to finally render the content in a <h2> element.

Scoped Slot with an Array

Although v-for can be used to send data from an array to a scoped slot, App.vue is code is essentially the same:

Example

SlotComp.vue:

				
					<template>
  <slot
    v-for="x in foods"
    :key="x"
    :foodName="x"
  ></slot>
</template>

<script>
  export default {
    data() {
      return {
        foods: ['Apple','Pizza','Rice','Fish','Cake']
      }
    }
  }
</script>
				
			

App.vue:

				
					<slot-comp v-slot="food">
  <h2>{{ food.foodName }}</h2>
</slot-comp>
				
			

Scoped Slot with an Array of Objects

Using v-for, a scoped slot can convey data from a variety of objects:

Example

SlotComp.vue:

				
					<template>
  <slot
    v-for="x in foods"
    :key="x.name"
    :foodName="x.name"
    :foodDesc="x.desc"
    :foodUrl="x.url"
  ></slot>
</template>

<script>
  export default {
    data() {
      return {
        foods: [
          { name: 'Apple', desc: 'Apples are a type of fruit that grow on trees.', url: 'img_apple.svg' },
          { name: 'Pizza', desc: 'Pizza has a bread base with tomato sauce, cheese, and toppings on top.', url: 'img_pizza.svg' },
          { name: 'Rice', desc: 'Rice is a type of grain that people like to eat.', url: 'img_rice.svg' },
          { name: 'Fish', desc: 'Fish is an animal that lives in water.', url: 'img_fish.svg' },
          { name: 'Cake', desc: 'Cake is something sweet that tastes good but is not considered healthy.', url: 'img_cake.svg' }
       ]
      }
    }
  }
</script>
				
			

App.vue:

				
					<slot-comp v-slot="food">
  <hr>
  <h2>{{ food.foodName }}<img :src=food.foodUrl></h2>
  <p>{{ food.foodDesc }}</p>
</slot-comp>
				
			

Static Data from a Scoped Slot

Static data, or data that is not part of the Vue instance’s data property, can also be sent via a scoped slot.

We don’t utilize v-bind when delivering static data.

To demonstrate the differences, we transmit one text that is static and one that is dynamically connected to the data instance in the example below.

Example

SlotComp.vue:

				
					<template>
  <slot
    staticText="This text is static"
    :dynamicText="text"
  ></slot>
</template>

<script>
  export default {
    data() {
      return {
        text: 'This text is from the data property'
      }
    }
  }
</script>
				
			

App.vue:

				
					<slot-comp v-slot="texts">
  <h2>{{ texts.staticText }}</h2>
  <p>{{ texts.dynamicText }}</p>
</slot-comp>
				
			

Named Scoped Slots

One can give names to scoped slots.

The slots inside the component must be given names using the ‘name’ property in order to use named scoped slots.

Additionally, we must use the v-slot directive, or shorthand #, to refer to the identified slot’s name in the parent component where we use it in order to get data from it.

Example

In this example the component is created one time referring to the slot “leftSlot”, and one time referring to the slot “rightSlot”.

SlotComp.vue:

				
					<template>
  <slot
    name="leftSlot"
    :text="leftText"
  ></slot>
  <slot
    name="rightSlot"
    :text="rightText"
  ></slot>
</template>

<script>
  export default {
    data() {
      return {
        leftText: 'This text belongs to the LEFT slot.',
        rightText: 'This text belongs to the RIGHT slot.'
      }
    }
  }
</script>
				
			

App.vue:

				
					<slot-comp #leftSlot="leftProps">
  <div>{{ leftProps.text }}</div>
</slot-comp>
<slot-comp #rightSlot="rightProps">
  <div>{{ rightProps.text }}</div>
</slot-comp>
				
			

As an alternative, we might create the component twice, using two distinct “template” tags, each of which would point to a distinct slot.

Example

In this example the component is created only one time, but with two “template” tags, each referring to a different slot.

SlotComp.vue is exactly the same as in the previous example.

App.vue:

				
					<slot-comp>

  <template #leftSlot="leftProps">
    <div>{{ leftProps.text }}</div>
  </template>

  <template #rightSlot="rightProps">
    <div>{{ rightProps.text }}</div>
  </template>

</slot-comp>
				
			
Share this Doc

Vue Scoped Slots

Or copy link

Explore Topic