Scoped Slots in Vue

Welcome to The Coding College! In Vue, scoped slots allow you to pass data from a child component to the parent, making them ideal for scenarios where the parent controls how child-rendered content should look. Scoped slots enhance flexibility by enabling dynamic content rendering while maintaining clean and reusable component structures.

This guide will cover the basics of scoped slots, practical examples, and best practices to make the most of this feature.

What Are Scoped Slots?

A scoped slot is a slot that provides access to data (slot props) from the child component. Unlike regular slots, which simply inject content, scoped slots share data with the parent, allowing for dynamic customization of child content.

Syntax Overview

Scoped slots use the v-slot directive to bind data from the child to the parent.

<ChildComponent>
  <template v-slot:slotName="slotProps">
    <!-- Content using slotProps -->
  </template>
</ChildComponent>
  • slotName: The name of the slot being targeted.
  • slotProps: The data exposed by the child component.

Example: Basic Scoped Slot

Child Component

File: ChildComponent.vue

<template>
  <div>
    <slot :message="message"></slot>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello from ChildComponent!'
    };
  }
};
</script>

Parent Component

File: App.vue

<template>
  <ChildComponent>
    <template v-slot:default="{ message }">
      <h1>{{ message }}</h1>
    </template>
  </ChildComponent>
</template>

<script>
import ChildComponent from './components/ChildComponent.vue';

export default {
  components: {
    ChildComponent
  }
};
</script>

Rendered Output

<div>
  <h1>Hello from ChildComponent!</h1>
</div>

Here, the message is passed from the child to the parent through the slot props and rendered dynamically.

Practical Use Case: Rendering a List

Scoped slots are particularly useful when you need to render lists with varying layouts.

Child Component

File: ListComponent.vue

<template>
  <ul>
    <li v-for="item in items" :key="item.id">
      <slot :item="item"></slot>
    </li>
  </ul>
</template>

<script>
export default {
  props: {
    items: Array
  }
};
</script>

Parent Component

File: App.vue

<template>
  <ListComponent :items="users">
    <template v-slot:default="{ item }">
      <strong>{{ item.name }}</strong> - {{ item.email }}
    </template>
  </ListComponent>
</template>

<script>
import ListComponent from './components/ListComponent.vue';

export default {
  components: {
    ListComponent
  },
  data() {
    return {
      users: [
        { id: 1, name: 'Alice', email: '[email protected]' },
        { id: 2, name: 'Bob', email: '[email protected]' }
      ]
    };
  }
};
</script>

Rendered Output

<ul>
  <li>
    <strong>Alice</strong> - [email protected]
  </li>
  <li>
    <strong>Bob</strong> - [email protected]
  </li>
</ul>

This approach lets you reuse the ListComponent with any kind of custom content.

Default Fallback for Scoped Slots

Scoped slots can include default content that renders if no content is provided from the parent.

Example

Child Component

<template>
  <div>
    <slot :message="message">Default Fallback Content</slot>
  </div>
</template>

If the parent doesn’t provide slot content, the fallback (“Default Fallback Content”) will be displayed.

Using Shorthand for Scoped Slots

Vue provides a shorthand syntax for scoped slots:

<ChildComponent>
  <template #default="{ message }">
    <h1>{{ message }}</h1>
  </template>
</ChildComponent>

This is equivalent to:

<ChildComponent>
  <template v-slot:default="{ message }">
    <h1>{{ message }}</h1>
  </template>
</ChildComponent>

Dynamic Scoped Slots

You can dynamically switch between different slots using variables.

Example

<ChildComponent>
  <template v-slot:[dynamicSlotName]="slotProps">
    <p>{{ slotProps.message }}</p>
  </template>
</ChildComponent>

Here, the slot name (dynamicSlotName) is determined dynamically in the parent.

Best Practices for Scoped Slots

  1. Use Meaningful Names: Name slots and slot props descriptively to enhance code readability.
  2. Document Slot Props: Clearly define what data the child component exposes in the scoped slot.
  3. Avoid Overuse: Use scoped slots when the child needs to pass data to the parent. For simple cases, regular slots may suffice.
  4. Combine with Reusability: Design components to maximize reusability and flexibility with scoped slots.

When to Use Scoped Slots

  1. Custom Render Logic: For components like lists, tables, or grids that require variable layouts.
  2. Data-Driven UI: To pass dynamic data from a child to a parent for rendering.
  3. Reusable Patterns: To create highly flexible and reusable components.

Conclusion

Scoped slots in Vue enable dynamic, data-driven content rendering that empowers developers to create reusable and customizable components. By mastering scoped slots, you can unlock the full potential of Vue’s component architecture.

For more in-depth Vue tutorials and insights, visit The Coding College.

Leave a Comment