Slots and Advanced Patterns
Introduction And Overview
Welcome back to the course on Building with Vue Components. So far, you have learned how to build components using the Composition API, pass data with props, and communicate between components using custom events. In this lesson, we will take your component skills to the next level by exploring Vue slots and some advanced component patterns.
By the end of this lesson, you will understand how to use slots to make your components more flexible and reusable. You will see how to build a base UI component that can accept custom content, and how to use both default and named slots to organize your layouts. You will also learn best practices for designing components that are easy to maintain and scale as your application grows.
Recap And Context
Before we dive into slots, let’s quickly review what you have learned so far. In the previous lessons, you saw how to use props to pass data from a parent component to a child, and how to use custom events to send information back from the child to the parent. This pattern is the foundation of most Vue applications and helps keep your components focused and predictable.
However, sometimes you need even more flexibility. For example, you might want to create a reusable card component that can display different types of content, or you might want to let a parent component decide what buttons or actions appear in a child component. This is where slots come in. Slots allow you to pass not just data, but also custom content and layouts from a parent to a child component. This adds another layer of flexibility to your component design.
Understanding Vue Slots
A slot in Vue is a placeholder inside a child component where the parent can inject its own content. There are two main types of slots: default slots and named slots.
A default slot is the most basic type. It is used when you want to pass content into a component without specifying a name. For example, if you have a BaseCard component, you can place any content between its opening and closing tags, and that content will appear wherever the default <slot></slot> is placed inside the component.
A named slot allows you to define multiple placeholders in your component, each with a unique name. This is useful when you want to give the parent more control over where specific pieces of content go. For example, you might have a slot for the main content and another slot for action buttons.
The main benefit of using slots is that they make your components much more reusable. Instead of hard-coding content or layouts, you can let the parent decide what to display. This is especially helpful for building UI libraries or complex layouts.
Building The BaseCard Component With Slots
Let’s look at a real example. Here is the BaseCard.vue component, which uses both a default slot and a named slot called actions:
In this component, the default slot is placed inside the .content div. Any content you put between <BaseCard> and </BaseCard> in the parent will appear here. The named slot, actions, is placed inside the .actions div. To use this slot, the parent must provide content using the #actions template syntax.
This design allows you to use BaseCard for many different purposes. You can put any content you want in the main area, and you can add custom action buttons or links in the actions area.
Enhancing TodoItem With Slot Integration
Now, let's see how the TodoItem.vue component uses the BaseCard component and its slots. Here is the relevant code:
In this example, the main content of the to-do item (the checkbox and the text) is placed inside the default slot of BaseCard. The delete button is placed inside a <template #actions> block, which targets the named actions slot in BaseCard.
Understanding the # syntax: The #actions is a shorthand syntax introduced in Vue 3. It's equivalent to writing <template v-slot:actions>. Both mean "put this content into the named slot called 'actions'". The # shorthand is more concise and is the preferred modern style. Here's the comparison:
The itemClasses computed property is used to apply a special style when the to-do is completed. This class is passed to the BaseCard using the :class binding, so the card's appearance changes based on the state of the to-do.
When you use this component, the output will look like this:

The checkbox and text appear on the left, and the delete button appears on the right, thanks to the slot structure in BaseCard.
Advanced Patterns And Best Practices
When designing components with slots, it is important to keep your components focused and flexible. Use default slots for the main content and named slots for areas where you expect the parent to provide specific content, such as action buttons or footers.
Try to avoid making your components too complex. If you find yourself adding many named slots, consider whether your component is doing too much and if it can be broken down into smaller pieces. Always document your slots clearly so other developers know how to use your component.
Slots are especially useful for building UI libraries or design systems, where you want to provide a consistent structure but allow for custom content. By combining slots with props and events, you can create components that are both powerful and easy to use.
Remember, in the CodeSignal environment, all necessary libraries are pre-installed, so you can focus on writing and experimenting with your components without worrying about setup.
Summary And Next Steps
In this lesson, you learned how to use Vue slots to make your components more flexible and reusable. You saw the difference between default and named slots, and how to use them in real components like BaseCard and TodoItem. You also learned some best practices for designing clean and maintainable components with slots.
Next, you will get hands-on practice with these concepts. You will have the chance to build your own components using slots, experiment with different layouts, and see how slots can help you create more powerful and reusable UI elements. This will prepare you for even more advanced patterns in Vue component development.
