阿里云主机折上折
  • 微信号
Current Site:Index > <slot> - Web component slot

<slot> - Web component slot

Author:Chuan Chen 阅读数:41348人阅读 分类: HTML

<slot> is one of the core tags in Web Components technology, used to define slots in custom elements for dynamic content distribution. It significantly enhances component reusability and flexibility, particularly excelling in scenarios requiring dynamic content injection.

Basic Concepts of <slot>

The <slot> tag allows developers to reserve placeholders in a custom element's template, where external content can be inserted. It is similar to the slot mechanism in Vue or React but is part of the native HTML specification. The default content inside the slot is displayed when no external content is provided.

html 复制代码
<!-- Custom element template -->
<template id="my-component">
  <div>
    <slot name="header">Default Header</slot>
    <slot>Default Content</slot>
  </div>
</template>

<!-- Using the custom element -->
<my-component>
  <h1 slot="header">Custom Header</h1>
  <p>This is inserted content</p>
</my-component>

Named Slots and Default Slots

Slots are categorized into named slots and default slots. Named slots are identified by the name attribute, and external content must specify the target slot using the slot attribute. Unnamed slots serve as default slots.

html 复制代码
<template id="user-card">
  <div class="card">
    <slot name="avatar">
      <img src="default-avatar.png" alt="Default Avatar">
    </slot>
    <slot name="name">Unknown User</slot>
    <slot>No description available</slot>
  </div>
</template>

<!-- Actual usage -->
<user-card>
  <img slot="avatar" src="user-123.jpg" alt="User Avatar">
  <span slot="name">John Doe</span>
  <p>Frontend Engineer, passionate about Web Components</p>
</user-card>

Fallback Content for Slots

When no external content is provided for a slot, the content inside the <slot> tag serves as fallback content. This feature is often used for default styling or placeholders.

html 复制代码
<template id="alert-box">
  <div class="alert">
    <slot name="icon">⚠️</slot>
    <slot>An unknown error occurred</slot>
  </div>
</template>

<!-- Overriding only part of the slots -->
<alert-box>
  <span slot="icon"></span>
</alert-box>

CSS Styling for Slots

The ::slotted() pseudo-element can be used to select and style slotted content. Note: This selector only affects top-level slotted elements.

html 复制代码
<style>
  my-component::slotted(h1) {
    color: #ff5722;
    font-size: 2em;
  }
  ::slotted(p) {
    background: #f5f5f5;
  }
</style>

Dynamic Slot Content

JavaScript can dynamically manipulate slot content. The slotchange event can be used to listen for changes in slot content.

javascript 复制代码
class DynamicSlot extends HTMLElement {
  constructor() {
    super();
    const shadow = this.attachShadow({ mode: 'open' });
    shadow.innerHTML = `
      <slot name="dynamic"></slot>
    `;
    shadow.querySelector('slot').addEventListener('slotchange', (e) => {
      console.log('Slot content changed:', e.target.assignedNodes());
    });
  }
}
customElements.define('dynamic-slot', DynamicSlot);

Relationship Between Slots and Shadow DOM

In Shadow DOM, <slot> acts as a bridge connecting external Light DOM and internal Shadow DOM. The browser "distributes" content from the Light DOM to the corresponding slots.

html 复制代码
<template id="shadow-demo">
  <style>
    :host { display: block; border: 1px dashed #ccc; }
  </style>
  <slot></slot>
  <slot name="footer"></slot>
</template>

<script>
  class ShadowDemo extends HTMLElement {
    constructor() {
      super();
      const template = document.getElementById('shadow-demo');
      this.attachShadow({ mode: 'open' }).appendChild(template.content.cloneNode(true));
    }
  }
  customElements.define('shadow-demo', ShadowDemo);
</script>

<!-- Usage example -->
<shadow-demo>
  Main content
  <div slot="footer">Footer content</div>
</shadow-demo>

Advanced Slot Patterns

Multiple slots can be combined to create complex layouts. Naming and nesting slots enable highly customizable component structures.

html 复制代码
<template id="advanced-card">
  <div class="card">
    <header>
      <slot name="title"></slot>
      <slot name="subtitle"></slot>
    </header>
    <div class="content">
      <slot></slot>
    </div>
    <footer>
      <slot name="actions">
        <button>Default Button</button>
      </slot>
    </footer>
  </div>
</template>

<!-- Usage example -->
<advanced-card>
  <h2 slot="title">Advanced Card</h2>
  <p slot="subtitle">Using multiple named slots</p>
  <p>This is the main content area of the card...</p>
  <div slot="actions">
    <button>Confirm</button>
    <button>Cancel</button>
  </div>
</advanced-card>

Performance Considerations for Slots

While slots offer great flexibility, frequent updates to slot content can cause performance issues. In dynamic scenarios, it is recommended to use MutationObserver or custom events for optimization.

javascript 复制代码
class OptimizedSlot extends HTMLElement {
  constructor() {
    super();
    this._observer = new MutationObserver(() => this._handleChanges());
  }

  connectedCallback() {
    this._observer.observe(this, { childList: true });
  }

  _handleChanges() {
    // Batch process slot changes
  }
}

Browser Compatibility and Polyfill

Modern browsers widely support <slot>, but for older browsers, the webcomponentsjs polyfill can be used. Note that the polyfill may not fully replicate native slot behavior.

html 复制代码
<!-- Load polyfill -->
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@2.6.0/webcomponents-bundle.js"></script>

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.