Vue v-slot Directive

Modern syntax for working with named and scoped slots

🎯 What is v-slot?

The v-slot directive is the modern way to define slot content in Vue. It provides a unified syntax for named slots and scoped slots, making your code cleaner and more readable than the old slot syntax.


<!-- Modern v-slot syntax -->
<Card>
  <template v-slot:header>
    <h2>Title</h2>
  </template>
</Card>

<!-- Shorthand -->
<Card>
  <template #header>
    <h2>Title</h2>
  </template>
</Card>
                                    

v-slot Features

📝

Named Slots

Target specific slot locations

<template v-slot:header>
  Content
</template>

Shorthand Syntax

Use # for cleaner code

<template #header>
  Content
</template>
🔗

Scoped Slots

Access child component data

<template #default="slotProps">
  {{ slotProps.item }}
</template>
🎨

Destructuring

Extract specific properties

<template #default="{ item }">
  {{ item }}
</template>

🔹 Basic v-slot Usage

Use v-slot to target named slots:

🔸 Child Component (Layout.vue)

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

🔸 Parent Component

<template>
  <Layout>
    <template v-slot:header>
      <h1>My Website</h1>
    </template>
    
    <p>Main content here</p>
    
    <template v-slot:footer>
      <p>© 2025 My Company</p>
    </template>
  </Layout>
</template>

Output:

My Website

Main content here

© 2025 My Company

🔹 Shorthand Syntax (#)

Use the # symbol as shorthand for v-slot:

<template>
  <Card>
    <!-- Full syntax -->
    <template v-slot:header>
      <h2>Full Syntax</h2>
    </template>
    
    <!-- Shorthand (recommended) -->
    <template #title>
      <h3>Shorthand Syntax</h3>
    </template>
    
    <!-- Default slot -->
    <template #default>
      <p>Content</p>
    </template>
  </Card>
</template>

Best Practice: Use the # shorthand for cleaner, more readable code.

🔹 Default Slot with v-slot

Target the default (unnamed) slot:

<template>
  <Container>
    <!-- Method 1: Direct content (no template) -->
    <p>This goes to default slot</p>
    
    <!-- Method 2: Explicit default slot -->
    <template #default>
      <p>Explicit default slot</p>
    </template>
  </Container>
</template>

🔹 v-slot with Scoped Slots

Access data from child component:

<!-- Child Component (UserList.vue) -->
<template>
  <div>
    <div v-for="user in users" :key="user.id">
      <slot :user="user" :index="index"></slot>
    </div>
  </div>
</template>

<!-- Parent Component -->
<template>
  <UserList>
    <template #default="slotProps">
      <p>{{ slotProps.user.name }}</p>
    </template>
  </UserList>
</template>

🔹 Destructuring Slot Props

Extract specific properties from slot props:

<template>
  <TodoList>
    <!-- Destructure the slot props -->
    <template #default="{ item, index, remove }">
      <div>
        <span>{{ index + 1 }}. {{ item.text }}</span>
        <button @click="remove(item.id)">Delete</button>
      </div>
    </template>
  </TodoList>
</template>

Tip: Destructuring makes your code cleaner by directly accessing the properties you need.

🔹 Multiple Named Slots with v-slot

Combine multiple named slots in one component:

<template>
  <Modal>
    <template #header>
      <h2>Confirm Action</h2>
    </template>
    
    <template #body>
      <p>Are you sure you want to proceed?</p>
    </template>
    
    <template #footer>
      <button>Cancel</button>
      <button>Confirm</button>
    </template>
  </Modal>
</template>

🔹 Dynamic Slot Names

Use dynamic slot names with v-slot:

<template>
  <Component>
    <template v-slot:[dynamicSlotName]>
      <p>Dynamic slot content</p>
    </template>
    
    <!-- Shorthand -->
    <template #[dynamicSlotName]>
      <p>Dynamic slot content</p>
    </template>
  </Component>
</template>

<script setup>
import { ref } from 'vue'
const dynamicSlotName = ref('header')
</script>

🧠 Test Your Knowledge

What is the shorthand symbol for v-slot?