头图

详解Slots.001

foreword

Students who are familiar with Vue should know the concept of "slot". By using slots, the organization of page content can be more flexible.

There is also the concept of slots in the Web Components system. Today we will take a look at Slots in detail. This article mainly includes the following contents:

  • Why use Slots?
  • Related Features of Slots

The role of Slots

Let's first look at a template element:

<template>
    <div class = "header">MY CARD</div>
    <div class="details">
        My name is 编程三昧。
    </div>
</template>

Since it is a template, it means that it will be used in many places, but there will be a problem here: All places where this template is used will display the content in the template , that is, not everyone's name is called" Programming Samadhi".

In this case, people with other names cannot use this template. Obviously, this is contrary to the original intention of using the template. The scope of use of this template is too narrow and there is no universality.

The key to making this template generic is whether the content displayed in .details is generic.

Think about it with your brain, can we set the "programming samadhi" as dynamic content, and whoever uses this template will pass in his own name. Exactly, Slots (slots) can achieve this effect, as follows:

<!--在模板中使用 slot 进行占位-->
<template id="cardTmp">
    <div class="header">MY CARD</div>
    <div class="details">
        My name is <slot name="userName">编程三昧</slot>。
    </div>
</template>

<!--在使用上面模板的自定义元素中给 slot 传值-->
<my-card>
    <span slot="userName">插槽传值</slot>
</my-card>

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

The corresponding JS code is as follows:

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

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

Realize the effect:

image-20220211221138468

Through the above example, we can summarize the role of Slots in one sentence: The role of Slots is to pass values to template elements to enhance the flexibility and versatility of template elements.

Related Features of Slots

For the relevant features of Slots, I explain them one by one in the form of Q&A.

What does the name attribute of Slots do?

Slots with the specified name are called "named slots", where name is the unique identifier of the slot.

The slot attribute with the same value as Slots.name is required on the element that introduces the slot content. See the code below:

<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">编程三昧</slot>
</my-card>

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

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

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

running result:

image-20220211231116878

Slots are not inserted because the value of the incoming slot attribute does not match the value of the name attribute of Slots.

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

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

Remove the span element in the above two custom elements my-card , without passing any value, that is, change it to this:

<my-card></my-card>

The effect after running:

image-20220211222440918

It can be seen that if does not pass a value to Slots, then Slots will display its own preset content .

In fact, combining the above two points, we can also draw a conclusion: If refers to Slots, only the content of Slots corresponding to the name will be displayed, and the rest of Slots will not display .

Can Slots be used in normal DOM?

The "normal DOM" here is relative to the Shadow DOM, which refers to the document object where the page is located.

code show as below:

<slot name="userName">Slots 预设值</slot>
<div slot="userName">bcsm</div>

The display is as follows:

image-20220211223746968

Summary: uses Slots in the normal DOM, it will be directly rendered on the page, and does not have the slot effect .

Do Slots have to be used in Templates?

In the example we saw earlier, Slots are in Templates, does that mean that Slots must be used in Templates to take effect?

Because it has been verified that the Slots in the normal DOM are invalid, so we do a test in the Shadow DOM, the code is as follows:

<body>
    <h1>不在 Templates 中使用 Slots</h1>
    <div id="templ">
        <slot name="userName">这是 Slots 预设值</slot>
    </div>
    <my-paragraph>
        <span slot="userName">编程三昧</span>
    </my-paragraph>
    <script>
        class MyParagraph extends HTMLElement {
            constructor () {
                super();
                const template = document.getElementById('templ');

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

The display effect is as follows:

image-20220211225448919

As can be seen from the display effect, after appending the normal DOM node containing Slots to Shadow DOM, Slots displays the incoming value, which means that Slots are effective.

Summary: Slots can take effect in Shadow DOM, not necessarily in Templates.

Can multiple Slots with the same name be used 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">编程三昧</slot>。
    </div>
</template>
<my-card>
    <span slot="userName">插槽传值1</span>
    <span slot="userName">插槽传值2</span>
</my-card>

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

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

display effect:

image-20220211232249789

Conclusion: A Slots can receive multiple incoming values, and they will all be parsed and displayed as .

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

In the above example, all the elements that pass values to Slots are sub-elements of the custom element, so is it not a direct sub-element?

code show as below:

<template id="cardTmp">
    <div class="header">MY CARD</div>
    <div class="details">
        My name is <slot name="userName">编程三昧</slot>。
    </div>
</template>
<my-card>
    <div>
        <span slot="userName">插槽传值1</span>
    </div>
</my-card>

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

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

Operation effect (value-passing invalidation):

image-20220211233044205

Conclusion: The element that passes value to Slots must be a direct child element of the custom element, otherwise the value passing is .

concluding remarks

The above is a summary of my knowledge about Slots. That's all I can think of at the moment. It's definitely not comprehensive. I hope you can correct me and add it!

~

~ This article is over, thanks for reading!

~

Learn interesting knowledge, meet interesting friends, and shape interesting souls!

Hello everyone, I am the author of 〖 Programming Samadhi Hermit King , my public account is " Programming Samadhi ", welcome to pay attention, I hope you can give me more advice!


编程三昧
54 声望10 粉丝

学习有趣的知识,交识有趣的朋友,造就有趣的灵魂!