DEV Community

Cover image for What is `useSlots` in Vue?
Jakub Andrzejewski
Jakub Andrzejewski

Posted on

What is `useSlots` in Vue?

Slots are one of Vue's most powerful and flexible features, enabling component composition by allowing you to pass content from a parent component to a child. In Vue 2, you accessed slots via the this.$slots object inside an options API component. But in Vue 3, with the Composition API, things have changed — enter useSlots.

In this article, we’ll explore what useSlots is, when and how to use it, and provide practical examples to clarify its purpose.

Enjoy!

🤔 What is useSlots?

useSlots is a helper function provided by Vue's Composition API that gives you access to the slots passed into a component. It returns an object containing all named slots as functions. This object is reactive and allows you to work with slot content inside the setup() function or by using the script setup syntax.

When you're building components using the Composition API, you no longer have access to this. That means this.$slots and this.$scopedSlots are unavailable. useSlots bridges that gap.

Use useSlots when:

  • You need to conditionally render slot content inside setup().
  • You want to check if a specific slot is provided.
  • You're manipulating or interacting with slot content programmatically.

Remember about following rules:

  • useSlots only works inside setup() or functions called within setup().
  • Slot functions should be treated as render functions and called within the render context.
  • For full type support in TypeScript, consider defining slot types explicitly.

🟢 Using useSlots in Vue?

Here’s a basic example of a component using useSlots:

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

const slots = useSlots();
</script>

<template>
  <div>
    <header v-if="slots.header">
      <slot name="header" />
    </header>
    <main>
      <slot />
    </main>
    <footer v-if="slots.footer">
      <slot name="footer" />
    </footer>
  </div>
</template>
Enter fullscreen mode Exit fullscreen mode

In this example, we’re using useSlots to determine if header or footer slots are provided before rendering them. This can help avoid unnecessary wrapper elements or conditional logic in the template.

📖 Learn more

If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this link or by clicking the image below:

Vue School Link

It covers most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉

✅ Summary

useSlots is a crucial part of working with the Composition API in Vue 3 when dealing with slot content. It empowers you to write more flexible and expressive components while staying fully within the Composition API paradigm.

Take care and see you next time!

And happy coding as always 🖥️

Top comments (2)

Collapse
 
eastmann profile image
Maxim Klochkov

I think it makes sense to mention that $slots is officially valid in the template section and according to the docs useSlots only used in script setup which is actually a rare case.

Collapse
 
nicooprat profile image
Nico Prat • Edited

I struggled for years with this method to try to prevent empty wrappers: performance issues because of rerender, false negatives because the missing wrapper prevents its slot to be displayed again, and so on.

The only viable fix was to stop relying on useSlot and just add a CSS rule, like this:

<header>
  <slot name="header" />
</header>
Enter fullscreen mode Exit fullscreen mode
header:empty {
  display: none;
}
Enter fullscreen mode Exit fullscreen mode

Or, with Tailwind:

<header class="empty:hidden">
  <slot name="header" />
</header>
Enter fullscreen mode Exit fullscreen mode

Until there's a native way of checking whether a slot is full or empty, I wouldn't recommend using useSlot at all.