Understanding Vue.js Slots

May 13, 2019

Slots allow you to embed arbitrary content in a Vue component. Slots are the Vue equivalent to transclusion in Angular and child props in React.

For example, suppose you wanted a component called green that added a green background behind child content. Here's an example of such a component using slots.

Vue.component('green', {
  // The `<slot></slot>` part will be replaced with child content.
  template: `
    <div style="background-color: #00ff00">
      <slot></slot>
    </div>
  `
});

const app = new Vue({
  // The `<h1>` is the child content.
  template: `
    <green>
      <h1>Hello, World!</h1>
    </green>
  `
});

You can also define default inner HTML. If there's no inner HTML underneath <green></green>, Vue will use the inner HTML of <slot></slot> as shown below.

Vue.component('green', {
  // The inner HTML of `<slot></slot>` is the default.
  template: `
    <div style="background-color: #00ff00">
      <slot>
        <h2>Hello, World!</h2>
      </slot>
    </div>
  `
});

const app = new Vue({
  // No inner HTML
  template: `<green></green>`
});

Named Slots

Sometimes you need multiple slots. For example, suppose you're writing a brand component that has two slots, 'name' and 'logo'.

Vue.component('brand', {
  // 2 slots named 'logo' and 'name'.
  template: `
    <div class="brand">
      <div class="logo">
        <slot name="logo"></slot>
      </div>
      <div class="name">
        <a href="/">
          <slot name="name"></slot>
        </a>
      </div>
    </div>
  `
});

const app = new Vue({
  // `template v-slot:name` is how you insert content into a slot named
  // 'name'
  template: `
    <brand>
      <template v-slot:logo>
        <img src="https://masteringjs.io/assets/logo.png">
      </template>
      <template v-slot:name>
        Mastering JS
      </template>
    </brand>
  `
});

The output HTML looks like this:

<div data-server-rendered="true" class="brand">
  <div class="logo">
    <img src="http://masteringjs.io/assets/logo.png">
  </div>
  <div class="name">
    <a href="/">
      Mastering JS
    </a>
  </div>
</div>

Here's the rendered HTML:


More Vue Tutorials