Menu
×
   ❮   
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP HOW TO W3.CSS C C++ C# BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS R TYPESCRIPT ANGULAR GIT POSTGRESQL MONGODB ASP AI GO KOTLIN SASS VUE DSA GEN AI SCIPY AWS CYBERSECURITY DATA SCIENCE
     ❯   

Vue Tutorial

Vue HOME Vue Intro Vue Directives Vue v-bind Vue v-if Vue v-show Vue v-for Vue Events Vue v-on Vue Methods Vue Event Modifiers Vue Forms Vue v-model Vue CSS Binding Vue Computed Properties Vue Watchers Vue Templates

Scaling Up

Vue Why, How and Setup Vue First SFC Page Vue Components Vue Props Vue v-for Components Vue $emit() Vue Fallthrough Attributes Vue Scoped Styling Vue Local Components Vue Slots Vue v-slot Vue Scoped Slots Vue Dynamic Components Vue Teleport Vue HTTP Request Vue Template Refs Vue Lifecycle Hooks Vue Provide/Inject Vue Routing Vue Form Inputs Vue Animations Vue Animations with v-for Vue Build Vue Composition API

Vue Reference

Vue Built-in Attributes Vue Built-in Components Vue Built-in Elements Vue Component Instance Vue Directives Vue Instance Options Vue Lifecycle Hooks

Vue Examples

Vue Examples Vue Exercises Vue Quiz Vue Syllabus Vue Study Plan Vue Server Vue Certificate

Scoped Slots

A Scoped slot provides local data from the component so that the parent can choose how to render it.

Send Data to Parent

We use v-bind in the component slot to send local data to the parent:

SlotComp.vue:

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

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

The data inside the component can be referred to as 'local' because it is not accessible to the parent unless it is sent up to the parent like we do here with v-bind.


Receive Data from Scoped Slot

The local data in the component is sent with v-bind, and it can be received in the parent with v-slot:

Example

App.vue:

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

In the example above, 'dataFromSlot' is just a name we can choose ourselves to represent the data object we receive from the scoped slot. We get the text string from the slot by using the 'lclData' property, and we use interpolation to finally render the text in an <h2> tag.


Scoped Slot with an Array

A scoped slot can send data from an array by using v-for, but the code in App.vue is basically 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>
Run Example »

Scoped Slot with an Array of Objects

A scoped slot can send data from an array of objects by using v-for:

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>
Run Example »

Static Data from a Scoped Slot

A scoped slot can also send static data, that is data that does not belong to the data property of the Vue instance.

When sending static data we do not use v-bind.

In the example below we send one static text, and one text bound dynamically to the data instance so that we can see the difference.

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>
Run Example »

Named Scoped Slots

Scoped slots can be named.

To use named scoped slots we need to name the slots inside the component with the 'name' attribute.

And to receive data from a named slot we need to refer to that name in the parent where we use the component, with the v-slot directive, or shorthand #.

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>
Run Example »

Alternatively, we can create the component one time, with two different "template" tags, each "template" tag referring to a different 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>
Run Example »

Vue Exercises

Test Yourself With Exercises

Exercise:

What directives are needed to provide data from a components slot to the parent?

Local data in a component is sent from a slot with , 
and it can be received in the parent with .

CompOne.vue:
<slot :lclData="data"></slot>

App.vue:
<comp-one :"dataFromSlot">
  <h2>{{ dataFromSlot.lclData }}</h2>
</comp-one>

Start the Exercise



×

Contact Sales

If you want to use W3Schools services as an educational institution, team or enterprise, send us an e-mail:
sales@w3schools.com

Report Error

If you want to report an error, or if you want to make a suggestion, send us an e-mail:
help@w3schools.com

W3Schools is optimized for learning and training. Examples might be simplified to improve reading and learning. Tutorials, references, and examples are constantly reviewed to avoid errors, but we cannot warrant full correctness of all content. While using W3Schools, you agree to have read and accepted our terms of use, cookie and privacy policy.

Copyright 1999-2024 by Refsnes Data. All Rights Reserved. W3Schools is Powered by W3.CSS.