Javascript is required
Michael Hoffmann LogoMichael Hoffmann

Vue Tip: Check if Slot Is Empty

Michael Hoffmann - Senior Frontend Developer (Freelancer)
Michael Hoffmann
Jul 6, 2022
2 min read
|
10008 views
Template
Script
Slots
Vue Tip: Check if Slot Is Empty Image

You can check if a slot is empty, for example, only to render it if it is available or has content.

StackBlitz Project

The code for this tip is interactively available in the following StackBlitz project:

Check if a slot is empty

To check if a slot is empty, you can use $slots, an object representing the slots passed by the parent component.

Each slot is exposed on $slots as a function that returns an array of vnodes under the key corresponding to that slot's name. The default slot is exposed as $slots.default.

If a slot is a scoped slot, arguments passed to the slot functions are available to the slot as its slot props.

In the following example, the footer is only rendered if the slot with the name footer is present:

1
<template>
2
<footer v-if="$slots.footer">
3
<h3>My Footer Heading</h3>
4
<slot name="footer" />
5
</footer>
6
</template>
Vue 2 Code

Of course, you can use that functionality in Vue 2 as well:

1
<template>
2
<footer v-if="showFooter">
3
<h3>My Footer Heading</h3>
4
<slot name="footer" />
5
</footer>
6
</template>
7
8
<script>
9
export default {
10
data() {
11
return {
12
showFooter: false,
13
}
14
},
15
created() {
16
this.setShowSlots()
17
},
18
beforeUpdate() {
19
this.setShowSlots()
20
},
21
methods: {
22
setShowSlots() {
23
this.showFooter = this.$slots.footer?.[0]
24
},
25
},
26
}
27
</script>

useSlots composable

Usage of slots inside <script setup> should be relatively rare since you can directly access them as $slots in the template. In the rare case where you need them, you can use the useSlots composable:

1
<template>
2
<footer v-if="showFooter">
3
<h3>My Footer Heading</h3>
4
<slot name="footer" />
5
</footer>
6
</template>
7
8
<script setup>
9
import { useSlots } from 'vue'
10
11
const slots = useSlots()
12
const showFooter = () => {
13
return !!slots.footer
14
}
15
</script>
Info

useSlots is a runtime function that returns the equivalent of setupContext.slots. You can use it in normal Composition API functions as well.

Check if a slot has content

In some cases, you probably want to check if the slot is not empty and has content inside.

You can do that by checking the array of vnodes if they are empty or not:

1
<script setup lang="ts">
2
import { Comment, computed, useSlots } from 'vue'
3
4
const slots = useSlots()
5
6
function isSlotAvailable() {
7
return !!slots?.footer
8
}
9
10
function hasSlotContent(slot, props = {}) {
11
return !isSlotEmpty(slot, props)
12
}
13
14
function isSlotEmpty(slot, props = {}) {
15
return isVNodeEmpty(slot?.(props))
16
}
17
18
function isVNodeEmpty(vnode) {
19
return !vnode || asArray(vnode).every((vnode) => vnode.type === Comment)
20
}
21
22
function asArray(arg) {
23
return Array.isArray(arg) ? arg : arg != null ? [arg] : []
24
}
25
</script>
26
27
<template>
28
<div class="container">
29
<h3>Hello World</h3>
30
<span>isSlotAvailable: {{ isSlotAvailable() }}</span>
31
<span>hasSlotContent: {{ hasSlotContent(slots?.footer) }}</span>
32
<footer v-if="slots.footer">
33
<h3>My Footer Heading</h3>
34
<slot name="footer" />
35
</footer>
36
</div>
37
</template>

If you liked this Vue tip, follow me on Twitter to get notified about new tips, blog posts, and more. Alternatively (or additionally), you can subscribe to my weekly Vue newsletter:

New Vue & Nuxt tips delivered to your inbox:
I will never share any of your personal data.