JAVASCRIPT

Mastering Slots for Flexible and Reusable Vue 3 Components

Utilize default, named, and scoped slots in Vue 3 to build highly versatile and reusable components, allowing parent components to inject custom content and data.

// components/MyCard.vue
<template>
  <div class="card">
    <header class="card-header">
      <!-- Named Slot for Title -->
      <slot name="header">Default Card Header</slot>
    </header>
    <div class="card-content">
      <!-- Default Slot for Main Content -->
      <slot>Default Card Content</slot>
    </div>
    <footer class="card-footer">
      <!-- Scoped Slot for Footer, passing data to parent -->
      <slot name="footer" :year="currentYear" :author="cardAuthor">
        Default Card Footer &copy; {{ currentYear }} {{ cardAuthor }}
      </slot>
    </footer>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const currentYear = ref(new Date().getFullYear());
const cardAuthor = ref('Vue Dev');
</script>

<style scoped>
.card {
  border: 1px solid #ddd;
  border-radius: 8px;
  margin: 15px;
  width: 300px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  font-family: Arial, sans-serif;
}
.card-header {
  background-color: #f4f4f4;
  padding: 15px;
  border-bottom: 1px solid #eee;
  font-weight: bold;
  color: #333;
}
.card-content {
  padding: 15px;
  color: #555;
}
.card-footer {
  background-color: #f9f9f9;
  padding: 15px;
  border-top: 1px solid #eee;
  font-size: 0.9em;
  color: #777;
}
</style>


// App.vue (Parent Component Usage)
<template>
  <div>
    <h2>Using MyCard Component</h2>

    <!-- Card with default content only -->
    <MyCard>
      <p>This is the main content for the first card.</p>
    </MyCard>

    <!-- Card with named slots -->
    <MyCard>
      <template #header>
        <h3>My Custom Header</h3>
      </template>
      <p>This card has a custom header and main content.</p>
      <template #footer>
        <button>Read More</button>
      </template>
    </MyCard>

    <!-- Card with scoped slot -->
    <MyCard>
      <template #footer="{ year, author }">
        <span>&copy; {{ year }} {{ author }} - All rights reserved.</span>
      </template>
    </MyCard>
  </div>
</template>

<script setup>
import MyCard from './components/MyCard.vue';
</script>

<style>
body { font-family: Arial, sans-serif; margin: 0; padding: 20px; background-color: #f0f2f5; }
h2 { color: #2c3e50; }
</style>
How it works: This snippet showcases the power of Vue 3 slots for creating flexible and reusable components. It demonstrates three types: default slots (for main content), named slots (for specific regions like header or footer), and scoped slots. Scoped slots are particularly powerful as they allow the child component (`MyCard`) to pass data (`year`, `author`) back to the parent component where the slot content is defined, enabling highly dynamic and customizable component usage.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs