Courses Blog About
⬅️ Back to the course

What are slots?

vue-slots

Slots are Vue’s mechanism for transferring template content to components. They allow you to create flexible, reusable components with dynamic content.

Basic Slots

Parent component:

<template>
  <Card>
    <p>This content will be included in the slot</p>
  </Card>
</template>

<script setup>
import Card from './Card.vue'
</script>

The Card.vue component:

<template>
  <div class="card">
    <div class="card-header">
      <h3>Card title</h3>
    </div>
    <!-- The content will be inserted here -->
    <slot></slot>
  </div>
</template>

Named slots

Parent component:

<template>
  <Layout>
    <template v-slot:header>
      <h1>My headline</h1>
    </template>
    
    <template v-slot:default>
      <p>Main content</p>
    </template>
    
    <template v-slot:footer>
      <p>© 2023 My Website</p>
    </template>
  </Layout>
</template>

The Layout.vue component:

<template>
  <div class="layout">
    <header>
      <slot name="header"></slot>
    </header>
    <main>
      <slot></slot> <!-- default slot -->
    </main>
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

Scoped Slots (Slots with data)

The List.vue component:

<template>
  <ul>
    <li v-for="(item, index) in items" :key="index">
      <!-- Passing the item data to the slot -->
      <slot :item="item" :index="index"></slot>
    </li>
  </ul>
</template>

<script setup>
defineProps<{
    type: string[]; 
}>();
</script>

Parent component:

<template>
  <List :items="users">
    <!-- We receive data through the v-slot -->
    <template v-slot="{ item, index }">
      <p>{{ index + 1 }}. {{ item.name }} ({{ item.age }})</p>
    </template>
  </List>
</template>

<script setup>
import List from './List.vue'

const users = [
  { name: 'Alex', age: 28 },
  { name: 'Bob', age: 24 }
]
</script>

Dynamic slot names

<template>
  <DynamicSlot>
    <template v-slot:[dynamicSlotName]>
      Content for the dynamic slot
    </template>
  </DynamicSlot>
</template>

<script setup>
import { ref } from 'vue'
import DynamicSlot from './DynamicSlot.vue'

const dynamicSlotName = ref('header')
</script>

Practical tips

<slot>Backup content if nothing is transmitted</slot>

Conclusion

Homework assignment

<!-- Example of Tabs.vue -->
<template>
  <div class="tabs">
    <div class="tab-header">
      <slot name="header"></slot>
    </div>
    <div class="tab-content">
      <slot></slot>
    </div>
  </div>
</template>
frontline

FrontLine

Join us in telegram

Other interesting posts in a convenient format

Subscribe

Another lessons