SoFunction
Updated on 2025-04-13

Vue uses slots to achieve high multiplexing components

Preface

In modern front-end development, component development has become the mainstream, and the slots feature provides strong support for us to build flexible and reusable components. This article will explore slot characteristics in depth, including basic slots, named slots, scope slots, dynamic slot names and slot default content, and explain their application scenarios and usage methods through examples.

What is a slot

Slots are used to occupy a place in a child component, allowing the parent component to dynamically insert content when using a child component. The essence of a slot is a placeholder that allows the parent component to insert custom content at a predefined location of the child component, thus achieving a high degree of reuse and flexibility of the component.

Slot Type

Basic slot

Let’s start with the basic slot (default slot). Suppose you have a Card component, we usually want the content of this component to be determined by the outside. Let’s take a look at the following example:

<!--  -->
<template>
  <div class="card">
    <slot></slot>
  </div>
</template>

<script>
export default {
  name: 'Card'
}
</script>

<style>
.card {
  border: 1px solid #ccc;
  padding: 16px;
  border-radius: 8px;
}
</style>

Here, it is the slot. When we are using this Card component, we can pass any HTML content:

&lt;!--  --&gt;
&lt;template&gt;
  &lt;Card&gt;
    &lt;h1&gt;title&lt;/h1&gt;
    &lt;p&gt;This is a paragraph。&lt;/p&gt;
  &lt;/Card&gt;
&lt;/template&gt;

&lt;script&gt;
import Card from './'

export default {
  components: {
    Card
  }
}
&lt;/script&gt;

In this way, the Card component will render as:

&lt;div class="card"&gt;
  &lt;h1&gt;title&lt;/h1&gt;
  &lt;p&gt;This is a paragraph。&lt;/p&gt;
&lt;/div&gt;

Named slots

Sometimes, we need to define multiple slots in one component. This time the named slot comes in handy. We can name each slot and then fill the contents of those slots separately when using components.

Let’s take a look at a simple example:

<!--  -->
<template>
  <div class="card">
    <header>
      <slot name="header"></slot>
    </header>
    <main>
      <slot></slot>
    </main>
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

When using this component, we can:

&lt;!--  --&gt;
&lt;template&gt;
  &lt;Card&gt;
    &lt;template v-slot:header&gt;
      &lt;h1&gt;title&lt;/h1&gt;
    &lt;/template&gt;
    &lt;template v-slot:footer&gt;
      &lt;p&gt;Footer content&lt;/p&gt;
    &lt;/template&gt;
    &lt;p&gt;Subject content。&lt;/p&gt;
  &lt;/Card&gt;
&lt;/template&gt;

In this way, the Card component will render as:

&lt;div class="card"&gt;
 &lt;header&gt;
    &lt;h1&gt;title&lt;/h1&gt;
  &lt;/header&gt;
  &lt;main&gt;
    &lt;p&gt;Subject content。&lt;/p&gt;
  &lt;/main&gt;
  &lt;footer&gt;
    &lt;p&gt;Footer content&lt;/p&gt;
  &lt;/footer&gt;
&lt;/div&gt;

Scope slots

Sometimes, a child component needs to provide some data to the slot for use by the parent component. At this time we need scope slots. The scope slot allows the parent component to pass a function to the child component, which the child component can use to render the content.

Let's take a look at an example:

<!--  -->
<template>
  <ul>
    <slot :items="items"></slot>
  </ul>
</template>

<script>
export default {
  name: 'List',
  props: {
    items: {
      type: Array,
      required: true
    }
  }
}
</script>

Use this List component in the parent component and use slots to pass in rendering logic:

<!--  -->
<template>
  <List :items="items">
    <template v-slot:default="slotProps">
      <li v-for="item in " :key="">{{  }}</li>
    </template>
  </List>
</template>

<script>
import List from './'

export default {
  components: {
    List
  },
  data() {
    return {
      items: [
        { id: 1, name: 'Item 1' },
        { id: 2, name: 'Item 2' }
      ]
    }
  }
}
</script>

In this example, slotProps is the data object provided to the slot by the child component List. We are free to use this data in the parent component.

Dynamic slot name

In some cases, the slot's name may be dynamically generated. Vue allows us to use dynamic slot names, similar to dynamic attribute binding. Let’s take a look at an example:

<!--  -->
<template>
  <div>
    <slot :name="dynamicSlot"></slot>
  </div>
</template>

<script>
export default {
  name: 'DynamicSlot',
  props: {
    dynamicSlot: {
      type: String,
      required: true
    }
  }
}
</script>

In the parent component, we can dynamically specify the slot name according to the conditions:

&lt;!--  --&gt;
&lt;template&gt;
  &lt;div&gt;
    &lt;DynamicSlot :dynamicSlot="currentSlot"&gt;
      &lt;template v-slot:header&gt;
        &lt;h1&gt;This is the head slot content&lt;/h1&gt;
      &lt;/template&gt;
      &lt;template v-slot:footer&gt;
        &lt;p&gt;This is the content of the tail slot&lt;/p&gt;
      &lt;/template&gt;
    &lt;/DynamicSlot&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
import DynamicSlot from './'

export default {
  components: {
    DynamicSlot
  },
  data() {
    return {
      currentSlot: 'header' // Dynamically change to 'footer' to see different content    }
  }
}
&lt;/script&gt;

By modifying the value of currentSlot, we can dynamically switch to display different slot contents.

Common usage

Slot default content

Sometimes we want the slot to display some default content when it is not filled. This can be done by adding default content to the tag:

&lt;!--  --&gt;
&lt;template&gt;
  &lt;div&gt;
    &lt;slot&gt;This is the default content,Displayed if slot content is not provided&lt;/slot&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
export default {
  name: 'DefaultSlot'
}
&lt;/script&gt;

When using this component, if no slot content is provided, the default content will be displayed:

&lt;!--  --&gt;
&lt;template&gt;
  &lt;div&gt;
    &lt;DefaultSlot&gt;&lt;/DefaultSlot&gt;
    &lt;!-- Content can also be provided,This will overwrite the default content --&gt;
    &lt;DefaultSlot&gt;
      &lt;p&gt;Custom content&lt;/p&gt;
    &lt;/DefaultSlot&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
import DefaultSlot from './'

export default {
  components: {
    DefaultSlot
  }
}
&lt;/script&gt;

Slots and Event Delivery

In practical applications, we often need to interact with the parent component in slot content, such as passing click events. Let’s take a look at an example:

<!--  -->
<template>
  <div class="button-group">
    <slot></slot>
  </div>
</template>

<script>
export default {
  name: 'ButtonGroup'
}
</script>

<style>
.button-group {
  display: flex;
}
</style>

In the parent component, we pass the button as slot content and listen for the button click event:

&lt;!--  --&gt;
&lt;template&gt;
  &lt;div&gt;
    &lt;ButtonGroup&gt;
      &lt;button @click="handleClick('Button 1')"&gt;Button1&lt;/button&gt;
      &lt;button @click="handleClick('Button 2')"&gt;Button2&lt;/button&gt;
    &lt;/ButtonGroup&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
import ButtonGroup from './'

export default {
  components: {
    ButtonGroup
  },
  methods: {
    handleClick(buttonName) {
      alert(${buttonName} Clicked!);
    }
  }
}
&lt;/script&gt;

In this example, clicking any button will trigger the handleClick method and display the corresponding prompt message.

Slot reuse

Another powerful thing about slots is their reusable ability. By reusing slot contents between different components, maintainability and reusability of the code can be greatly improved.

<!--  -->
<template>
  <div class="modal">
    <header>
      <slot name="header"></slot>
    </header>
    <main>
      <slot></slot>
    </main>
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

<script>
export default {
  name: 'Modal'
}
</script>

<style>
.modal {
  border: 1px solid #ccc;
  padding: 16px;
  border-radius: 8px;
}
</style>

Use Modal components in different places and provide different slot contents:

&lt;!--  --&gt;
&lt;template&gt;
  &lt;div&gt;
    &lt;Modal&gt;
      &lt;template v-slot:header&gt;
        &lt;h1&gt;Modal box title1&lt;/h1&gt;
      &lt;/template&gt;
      &lt;p&gt;This is the content of the first modal box。&lt;/p&gt;
      &lt;template v-slot:footer&gt;
        &lt;button&gt;Sure&lt;/button&gt;
      &lt;/template&gt;
    &lt;/Modal&gt;

    &lt;Modal&gt;
      &lt;template v-slot:header&gt;
        &lt;h1&gt;Modal box title2&lt;/h1&gt;
      &lt;/template&gt;
      &lt;p&gt;This is the content of the second modal box。&lt;/p&gt;
      &lt;template v-slot:footer&gt;
        &lt;button&gt;Cancel&lt;/button&gt;
      &lt;/template&gt;
    &lt;/Modal&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
import Modal from './'

export default {
  components: {
    Modal
  }
}
&lt;/script&gt;

In this way, we can reuse the Modal components in different contexts, and simply change the content passed to the slot.

Summarize

The slot characteristics provide great flexibility and reusability for componentized development. Through basic slots, named slots, scope slots, dynamic slot names, and slot default content, we can create highly reusable components, thereby greatly improving development efficiency and code quality.

In component development, making good use of slot features can not only simplify the code structure, but also improve the maintainability and scalability of components. I hope that through this article, you can understand the power of slots more deeply, and flexibly apply these techniques in actual development to build more elegant and efficient applications.

The above is the detailed content of Vue using slots to achieve high reusable components. For more information about Vue slots to achieve high reusable components, please pay attention to my other related articles!