DEV Community

Cover image for Applying slots in Vue for a Tabs component
Francesco Di Donato
Francesco Di Donato

Posted on • Updated on

Applying slots in Vue for a Tabs component

I recently completed Udemy courses on Vue and Nuxt.js.
I decided to test this framework to build a Vaccine Tracker. Having a background in React, learning was smooth and natural.

An incredibly versatile element is the slot. From the first moment I wondered how they could be used for the construction of complex and at the same time versatile layouts. For example a Tabs component.

Tabs component implementation

As props it is sufficient that it receives a list of all the tabs to display.
In the state it is sufficient to keep track of the activated tab.
Finally, we need a method that is triggered when clicked on a different tab.

import Vue from 'vue'

export default Vue.extend({
  props: {
    labels: {
      type: Array,
      require: true,
  data() {
    return {
      activeLabel: this.$props.labels[0],
  methods: {
    onLabelClick(label) {
      this.activeLabel = label
Enter fullscreen mode Exit fullscreen mode

So far (syntax aside) nothing different from any other framework. However, the magic happens in the template:

    <div v-for="label in labels" :key="label" @click="onLabelClick(label)">
      {{ label }}
    <slot :name="activeLabel">Default {{ activeLabel }}</slot>
Enter fullscreen mode Exit fullscreen mode

That's all. One iteration to show each tab. Below is a slot whose name is updating when one of the tabs is clicked.

For the purposes of this post I ignore the style. You can get fancy!

Tabs component usage

Wherever you want to use this component just do as follows:

<Tabs :labels="['one', 'two', 'three']">
          <template #one>
          <template #two>
          <template #three>
Enter fullscreen mode Exit fullscreen mode

Of the different templates, only the one relating to the active tab will be shown.
It's amazing how so few lines can lead to such versatile behavior.

Thanks for reading,
Repo 📑

If you like it, let's get in touch
🐙, 🐦 and 💼

Top comments (0)