A named slot

<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>
Copy the code

A

exit without a name carries the implied name “default”. When feeding content to a named slot, we can use the V-slot directive on a

<base-layout>
  <template v-slot:header>
    <h1>Here might be a page title</h1>
  </template>

  <template v-slot:default>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </template>

  <template v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>
Copy the code

Note that V-slot can only be added to

Scope slot

Sometimes it is useful to give slot content access to data that is only available in child components. This is a common situation when a component is used to render an array of items, and we want to be able to customize how each item is rendered.

For example, we have a component that contains a list of todo-items.

app.component('todo-list', {
  data() {
    return {
      items: ['Feed a cat'.'Buy milk']}},template: ` 
      
  • {{ item }}
`
}) Copy the code

We might want to replace {{item}} with

for customization on the parent component.

<todo-list>
  <i class="fas fa-check"></i>
  <span class="green">{{ item }}</span>
</todo-list>
Copy the code

However, this won’t work because only the

component can access the item, and we’ll supply the slot content from its parent.

To make item available to slot content provided by the parent, we can add a

element and bind it as an attribute:

<ul>
  <li v-for="( item, index ) in items">
    <slot :item="item"></slot>
  </li>
</ul>
Copy the code

You can bind as many attributes to slots as you want.

<ul>
  <li v-for="( item, index ) in items">
    <slot :item="item" :index="index" :another-attribute="anotherAttribute"></slot>
  </li>
</ul>
Copy the code

Attributes bound to

elements are called slot prop. Now in parent scope, we can define the name of our supplied slot prop using v-slot with a value:

<todo-list>
  <template v-slot:default="slotProps">
    <i class="fas fa-check"></i>
    <span class="green">{{ slotProps.item }}</span>
  </template>
</todo-list>
Copy the code

In this example, we chose to name the object that contains all the slotProps slotProps, but you can use any name you like.

Exclusive default slot abbreviation syntax

In this case, the component’s label can be used as a template for the slot only if the content provided is the default slot. This allows us to use v-slot directly on components:

<todo-list v-slot:default="slotProps">
  <i class="fas fa-check"></i>
  <span class="green">{{ slotProps.item }}</span>
</todo-list>
Copy the code

And this could be even simpler. Just as unspecified content is assumed to correspond to the default slot, v-slot without arguments is assumed to correspond to the default slot:

<todo-list v-slot="slotProps">
  <i class="fas fa-check"></i>
  <span class="green">{{ slotProps.item }}</span>
</todo-list>
Copy the code

Note that the default slot abbreviation syntax should not be mixed with named slots, as this would result in undefined scope:

<! -- invalid, will result in warning -->
<todo-list v-slot="slotProps">
  <i class="fas fa-check"></i>
  <span class="green">{{ slotProps.item }}</span>
  
  <template v-slot:other="otherSlotProps">
    slotProps is NOT available here
  </template>
</todo-list>
Copy the code

Whenever multiple slots are present, always use the full

<todo-list>
  <template v-slot:default="slotProps">
    <i class="fas fa-check"></i>
    <span class="green">{{ slotProps.item }}</span>
  </template>

  <template v-slot:other="otherSlotProps">.</template>
</todo-list>
Copy the code

Deconstructing slot Prop

The inner workings of a scoped slot are to include the contents of your slot in a function passing in a single argument:

function (slotProps) {
  / /... Slot content...
}
Copy the code

This means that the value of the V-slot can actually be any JavaScript expression that can be used as a parameter in the function definition. You can also use ES2015 deconstruction to pass in a specific slot prop as follows:

<todo-list v-slot="{ item }">
  <i class="fas fa-check"></i>
  <span class="green">{{ item }}</span>
</todo-list>
Copy the code

This can make the template more concise, especially if the slot provides multiple prop. It also opens up other possibilities such as renaming item to todo:

<todo-list v-slot="{ item: todo }">
  <i class="fas fa-check"></i>
  <span class="green">{{ todo }}</span>
</todo-list>
Copy the code

You can even define alternate content for cases where slot prop is undefined:

<todo-list v-slot="{ item = 'Placeholder' }">
  <i class="fas fa-check"></i>
  <span class="green">{{ item }}</span>
</todo-list>
Copy the code

Dynamic slot name

Dynamic command parameters can also be used on v-slots to define dynamic slot names:

<base-layout>
  <template v-slot:[dynamicSlotName] >.</template>
</base-layout>
Copy the code

An abbreviation for named slot

Like v-on and v-bind, v-slot has an abbreviation that replaces everything before the argument (v-slot:) with the character #. For example, v-slot:header can be rewritten as #header:

<base-layout>
  <template #header>
    <h1>Here might be a page title</h1>
  </template>

  <template #default>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </template>

  <template #footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>
Copy the code

However, as with other instructions, this abbreviation is only available if it has arguments. This means that the following syntax is invalid:

<! -- This will trigger a warning -->

<todo-list# ="{ item }">
  <i class="fas fa-check"></i>
  <span class="green">{{ item }}</span>
</todo-list>
Copy the code

If you want to use abbreviations, you must always specify the slot name instead:

<todo-list #default="{ item }">
  <i class="fas fa-check"></i>
  <span class="green">{{ item }}</span>
</todo-list>
Copy the code

Excerpt from vUE documentation