/

Vue.js Slots: Positioning and Organizing Content in Components

Vue.js Slots: Positioning and Organizing Content in Components

Slots in Vue.js are a powerful feature that allows you to position and organize content within a component. They enable parent components to inject content into specific areas of a child component’s template.

Let’s start by understanding the basic concept of slots. In a component, you can either generate its output entirely or leave room for external content using slots. A slot represents a reserved space in the component’s output that awaits content injection.

To define a slot, you need to add <slot></slot> to the component’s template. Here’s an example:

1
2
3
Vue.component('user-information', {
template: '<div class="user-information"><slot></slot></div>'
})

When you use this component, any content placed between the opening and closing user-information tags will be inserted inside the slot placeholder, as shown below:

1
2
3
4
<user-information>
<h2>Hi!</h2>
<user-name name="Flavio"></user-name>
</user-information>

If you include content within the <slot></slot> tags, it serves as the default content in case nothing is passed in.

In more complex component layouts, you may need a better way to organize content, which is where named slots come into play. Named slots enable you to assign specific parts of a slot to particular positions within a component’s template layout. You can achieve this by using the slot attribute on any tag to assign content to that slot.

Anything placed outside of any template tag is added to the primary slot. To illustrate this, consider a page single file component. In its template, you can define two slots: main and sidebar. Here’s an example:

1
2
3
4
5
6
7
8
9
10
<template>
<div>
<main>
<slot></slot>
</main>
<aside>
<slot name="sidebar"></slot>
</aside>
</div>
</template>

To use these named slots, you provide the content using the template v-slot syntax in the parent component:

1
2
3
4
5
6
7
8
9
10
11
<page>
<template v-slot:sidebar>
<ul>
<li>Home</li>
<li>Contact</li>
</ul>
</template>

<h2>Page title</h2>
<p>Page content</p>
</page>

Alternatively, you can use the shorthand # syntax:

1
2
3
4
5
6
7
8
9
10
11
<page>
<template #sidebar>
<ul>
<li>Home</li>
<li>Contact</li>
</ul>
</template>

<h2>Page title</h2>
<p>Page content</p>
</page>

Please note that starting from Vue 2.6, the slot attribute has been deprecated in favor of v-slot. Additionally, v-slot should be added to a template tag (whereas slot could be applied to any tag).

Another useful feature related to slots is scoped slots. In a slot, you can’t directly access the data contained in the child component from the parent. However, Vue provides a way to achieve this using scoped slots. By binding props to the slot, you can access the child component’s data inside the slot. Here’s an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template>
<div>
<main>
<slot v-bind:dogName="dogName"></slot>
</main>
</div>
</template>

<script>
export default {
name: 'Page',
data: function() {
return {
dogName: 'Roger'
}
}
}
</script>

In the parent component, you can access the passed data using the template v-slot syntax:

1
2
3
4
5
<page>
<template v-slot="slotProps">
{{ slotProps.dogName }}
</template>
</page>

Alternatively, you can destructure the object on-the-fly and avoid using an intermediate variable:

1
2
3
4
5
<page>
<template v-slot="{ dogName }">
{{ dogName }}
</template>
</page>

With Vue.js slots, you have the flexibility to position and organize content within components, making it easier to create reusable and dynamic components.

tags: [“Vue.js”, “slots”, “named slots”, “scoped slots”, “component development”]