“This is the 26th day of my participation in the First Challenge 2022. For details: First Challenge 2022”

preface

Those of you familiar with Vue are familiar with the concept of “slots”, which allow for flexible organization of page content.

There are also Slots in Web Components. Today we are going to look at Slots in detail. This article covers the following:

  • Why do we use Slots?
  • Slots related features

The role of the Slots

Let’s start with a template element:

<template>
    <div class = "header">MY CARD</div>
    <div class="details">My name is Programming Samadhi.</div>
</template>
Copy the code

Since it is a template, that means it will be used in many places, but there is a problem: the contents of the template will be displayed everywhere the template is used, meaning that not everyone’s name is “Programming Samadhi”.

In this case, no one with any other name can use the template. Obviously, this defeats the purpose of using the template, which is too narrow to be universal.

The key to making this template universal is whether the content displayed in.Details is universal.

Let’s see if we can make “programming samadhi” dynamic, and whoever uses this template will pass in their name. Exactly. Slots (Slots) does this:

<! -- Use slot in template for placeholder -->
<template id="cardTmp">
    <div class="header">MY CARD</div>
    <div class="details">
        My name is <slot name="userName">Programming samadhi</slot>.</div>
</template>

<! Pass a value to slot in a custom element using the above template
<my-card>
    <span slot="userName">Slot by value</slot>
</my-card>

<my-card>
    <span slot="userName">web Components</slot>
</my-card>
Copy the code

The corresponding JS code is as follows:

class MyCard extends HTMLElement {
    constructor () {
        super(a);const template = document.getElementById('cardTmp');
        const templateContent = template.content;

        this.attachShadow({mode: 'open'}).appendChild(
            templateContent.cloneNode(true)); } } customElements.define('my-card', MyCard);
Copy the code

Effect:

From the example above, we can sum up the role of Slots in one sentence. Slots is all about passing values to template elements, which makes template elements more flexible and versatile.

Slots related features

I explained the features of Slots in question and answer format.

What does the name attribute of Slots do?

Slots with a named name are called named Slots. Name is the unique identifier of the slot.

You need to use the same slot attribute as the slot.name value on the element that imports slot content. Look at the following code:

<template id="cardTmp">
    <div class="header">MY CARD</div>
    <div class="details">
        My name is <slot name="userAge">19</slot>.</div>
</template>
<my-card>
    <span slot="userName">Programming samadhi</slot>
</my-card>

<my-card>
    <span slot="userName">web Components</slot>
</my-card>

<script>
    class MyCard extends HTMLElement {
        constructor () {
            super(a);const template = document.getElementById('cardTmp');
            const templateContent = template.content;

            this.attachShadow({mode: 'open'}).appendChild(
                templateContent.cloneNode(true)); } } customElements.define('my-card', MyCard);
</script>
Copy the code

Operation effect:

Slots is not inserted because the slot attribute value passed in does not match the name attribute value of Slots.

The slot attribute value must be the same as the name attribute value of Slots.

What happens if you don’t pass a value to Slots?

Remove the span element from the above two custom elements my-card without passing any values:

<my-card></my-card>
Copy the code

Effect after operation:

As you can see, if you don’t pass a value to Slots, Slots will display its own default content.

If there is a reference to Slots, only the name of Slots will be displayed. The rest of Slots will not be displayed.

Can Slots be used in the normal DOM?

The term “normal DOM” refers to the document object in which the page is located, as opposed to Shadow DOM.

The code is as follows:

<slot name="userName">Slots preset</slot>
<div slot="userName">bcsm</div>
Copy the code

The following information is displayed:

Summary: Normal DOM uses Slots, which renders directly on the page without Slots effect.

Does Slots have to be used in Templates?

In the example we saw earlier, Slots is in Templates. Does that mean that Slots has to be used in Templates to work?

Since we have already verified that Slots is not valid in the normal DOM, we will do a test in the Shadow DOM. The code is as follows:

<body>
    <h1>You don't use Slots in Templates</h1>
    <div id="templ">
        <slot name="userName">This is the Slots default</slot>
    </div>
    <my-paragraph>
        <span slot="userName">Programming samadhi</span>
    </my-paragraph>
    <script>
        class MyParagraph extends HTMLElement {
            constructor () {
                super(a);const template = document.getElementById('templ');

                this.attachShadow({mode: 'open'}).appendChild(
                    template.cloneNode(true)); } } customElements.define('my-paragraph', MyParagraph);
    </script>
</body>
Copy the code

The following information is displayed:

As you can see from the display, when the normal DOM node containing Slots is appended to the Shadow DOM, Slots displays the value passed in, which means that Slots is valid.

Summary: Slots works in Shadow DOM, not necessarily in Templates.

Can you use multiple Slots with the same name in a custom element?

Look at the code:

<template id="cardTmp">
    <div class="header">MY CARD</div>
    <div class="details">
        My name is <slot name="userName">Programming samadhi</slot>.</div>
</template>
<my-card>
    <span slot="userName">The slot passes a value of 1</span>
    <span slot="userName">The slot passes a value of 2</span>
</my-card>

<script>
    class MyCard extends HTMLElement {
        constructor () {
            super(a);const template = document.getElementById('cardTmp');
            const templateContent = template.content;

            this.attachShadow({mode: 'open'}).appendChild(
                templateContent.cloneNode(true)); } } customElements.define('my-card', MyCard);
</script>
Copy the code

Display effect:

Conclusion: A Slots slot can accept multiple incoming values and parse them out.

Does the pass element of Slots have to be a direct child of the custom element?

In the example above, all the elements passed to Slots are children of the custom element. Is that not true of indirect children?

The code is as follows:

<template id="cardTmp">
    <div class="header">MY CARD</div>
    <div class="details">
        My name is <slot name="userName">Programming samadhi</slot>.</div>
</template>
<my-card>
    <div>
        <span slot="userName">The slot passes a value of 1</span>
    </div>
</my-card>

<script>
    class MyCard extends HTMLElement {
        constructor () {
            super(a);const template = document.getElementById('cardTmp');
            const templateContent = template.content;

            this.attachShadow({mode: 'open'}).appendChild(
                templateContent.cloneNode(true)); } } customElements.define('my-card', MyCard);
</script>
Copy the code

Operation effect (failure of value transfer) :

Conclusion: The element passed to Slots must be a direct child of the custom element, otherwise the pass fails.

conclusion

So that’s a summary of my knowledge of Slots. That’s all I can think of so far. It’s definitely not comprehensive.

~

Thanks for reading!

~

Learn interesting knowledge, meet interesting friends, shape interesting soul!

Hello everyone, I am the author of “programming Samadhi”, I am king Yi, my public account is “programming Samadhi”, welcome to pay attention, I hope you can give me more advice!