Close read Vue official documentation series 🎉

The Slot design, inspired by the draft Web Components specification, uses the < Slot > element as an outlet for hosting distribution content.

The analogy for content distribution is that $attrs instance attributes distribute all attributes; The $Listeners instance attribute can be distributed like all events.

A slot is used inside a component to receive the content between the start tag and end tag of a custom element (a custom component), and then output the content at the specified location of the component content. If the template of a custom component does not contain a

element, the content of the custom element will be discarded.

Vue.component('custom-element', {
    template:'<p></p>'
});
Vue.component('custom-element-2', {
    template:'<p><slot></slot></p>'
});
Copy the code
<! -- This is custom element content is not displayed -->
<custom-element>This is custom element content</custom-element>

<! -- Normal display -->
<custom-element-2>This is custom element content</custom-element-2>
Copy the code

A slot can accept any type of content, including another component.

Compile scope

Everything in the parent template is compiled in the parent scope; Everything in a subtemplate is compiled in a subscope.

Slot content defined in the parent, compiled in the parent, part of the parent, will be introduced to the contents of the compiled to slot elements is performed by the component in the component after the show, follow the provisions of JavaScript in lexical scope slot content can only access the parent scope of data, and can not access slot elements in child components in the data.

Backup the content

The default value of the slot is rendered by default if the slot does not receive anything.

Vue.component('base-button', {
    template:'<slot>button</slot>'
});
Copy the code

The parent passes the value by placing the content between the start and end tags of the custom element, and then distributes the content through the

element inside the custom component.

A named slot

When more than one slot is needed to distribute content, the

element can be named to anchor the slot for the content output.

As the name implies, a named slot is a name for a slot when there are multiple slots.

Use the name attribute to name multiple slots, and an exit without a name will have the implied name “default.”

<script id="base-layout-template">
    <slot></slot>
    <slot name="other"></slot>
</script>
<script>
Vue.component('base-layout', {
    template:'#base-layout-template'});</script>
Copy the code

In practice, we group by

<base-layout>
    <p>Content</p>
    <template v-slot:header>Header & Menu & Nav</template>
    <template v-slot:footer>Footer</template>
</base-layout>
Copy the code

Here is:

Scope slot

From the compilation scope of the slot, we know that the contents of the slot defined in the parent component scope cannot get the data in the component where the slot element

resides. The purpose of a scoped slot is to allow data transfer from the inside of the slot to the outside of the slot, so that the contents of the slot can also access the data in the component where the slot element

resides.

The steps are as follows:

  1. usev-bindDirective for the current component<slot>Element binding slot Prop, which is then compiled and passed to the scope slot as parameters (data within the component).
  2. Slot contents in the parent scope<template>Elementv-slotInstruction and receives the previous step with the slot name as instruction parameter<slot>Element is bound to the slot Prop, so as to obtain data in the slot of the component where the slot is.
Vue.component('mouse-move', {
    template:'
      , data(){ return { xAxis:0, yAxis:0 } }, mounted(){ window.addEventListener('mousemove',e=>{ this.xAxis = e.clientX; this.yAxis = e.clientY; },{passive:true}); }})Copy the code
<mouse-move>
    <template v-slot:default="slotProps">
        <ul>
            <li>xAxis:{{slotProps.x}}</li>
            <li>yAxis:{{slotProps.y}}</li>
        </ul>
    </template>
</mouse-move>
Copy the code

If there are multiple named slots, receive the Prop bound to each slot separately. The default slot name is default or the slot name is empty.

<slot-example>
    <template v-slot="slotProps">{{slotProps.value}}</template>
    <template v-slot:other="otherSlotProps">        {{otherSlotProps.value}}</template>
</slot-example>
Copy the code

Exclusive default slot writing

If the component only provides a default slot, you can simply add the v-slot= “slotProps” directive to the component’s custom elements.

<slot-example v-slot="slotProps"></slot-example>
Copy the code

Is equivalent to

<slot-example>
    <template v-slot:default="slotProps"></template>
</slot-example>
Copy the code

It is possible to omit a

If there are multiple slots inside the component, the slot content must strictly use the

<slot-example>
    <template v-slot="slotProps"></template>
    <template v-slot:other="otherSlotProps"></template>
</slot-example>
Copy the code

Notice The name of the default slot is default.

Deconstruction slot

The slot content is compiled in the parent, wrapped in a function with a single argument, and passed to the child component, which executes it, along with the value of the slot Prop.

Vue combines all Props bound to the

element in the slotProps object as key-value pairs, which are then passed as arguments to methods that wrap the contents of slots, meaning that we can get the value of the Prop in the template in a much cleaner way using ES6’s deconstruction syntax.

<slot-example v-slot="{x, y}"></slot-example>
Copy the code

Dynamic Slot Name

The name of a named slot can be a dynamic value, which has the same effect as a dynamic instruction parameter.

<! --Definition-->
<slot :name="slotName" :values="vals"></slot>

<! --Usage-->
<slot-example>
    <template v-slot:[slotName] ="slotProps">
    </template>
</slot-example>
Copy the code

Short for named slot

As with v-ON and V-bind directives, we can use # to abbreviate v-slot directives

<template #default></template>
<template #other="otherSlotProps"></template>
Copy the code

The abbreviation V-slot instruction must have an instruction parameter.

Other applications

When designing reusable components that want to render different content based on the socket Prop bound to the child component, but also allow the parent component to customize the layout of parts, the “scoped slot” pattern is useful.

Here are some reusable Vue components based on the idea of “scope slots”.

  • Github.com/posva/vue-p…
  • Github.com/LinusBorg/p…
  • Github.com/Akryum/vue-…

conclusion

Use the name attribute of the

element to define a named slot, where the value of name can be default. The

element of a slot can also bind data from the component in which the slot is located to a Prop using the V-bind directive, which is passed in as a parameter when the contents of the slot are executed.

When you use a component with slot elements in the parent scope, you can receive a Prop corresponding to the named slot binding by binding it with the v-slot:[name]=”slotProps” directive.

  • #Can be used insteadv-slotInstructions are abbreviated and must contain instruction parameters.
  • The default slot name isdefault, can be omitted without writing.