<slot>-Web组件插槽
<slot>
是 Web Components 技术中的核心标签之一,用于在自定义元素中定义插槽,实现内容的动态分发。它让组件的复用性和灵活性大幅提升,尤其在需要动态内容注入的场景下表现突出。
<slot>
的基本概念
<slot>
标签允许开发者在自定义元素的模板中预留位置,外部使用时可以插入任意内容。它类似于 Vue 或 React 中的插槽机制,但属于原生 HTML 规范。插槽的默认内容在未提供外部内容时显示。
html
<!-- 自定义元素模板 -->
<template id="my-component">
<div>
<slot name="header">默认标题</slot>
<slot>默认内容</slot>
</div>
</template>
<!-- 使用自定义元素 -->
<my-component>
<h1 slot="header">自定义标题</h1>
<p>这是插入的内容</p>
</my-component>
具名插槽与默认插槽
插槽分为具名插槽和默认插槽。具名插槽通过 name
属性标识,使用时需通过 slot
属性指定目标插槽;未命名的插槽则作为默认插槽。
html
<template id="user-card">
<div class="card">
<slot name="avatar">
<img src="default-avatar.png" alt="默认头像">
</slot>
<slot name="name">未知用户</slot>
<slot>暂无简介</slot>
</div>
</template>
<!-- 实际使用 -->
<user-card>
<img slot="avatar" src="user-123.jpg" alt="用户头像">
<span slot="name">张三</span>
<p>前端工程师,热爱Web组件技术</p>
</user-card>
插槽的 fallback 内容
当外部未提供插槽内容时,<slot>
标签内的内容会作为 fallback 显示。这一特性常用于提供默认样式或占位符。
html
<template id="alert-box">
<div class="alert">
<slot name="icon">⚠️</slot>
<slot>发生未知错误</slot>
</div>
</template>
<!-- 只覆盖部分插槽 -->
<alert-box>
<span slot="icon">❗</span>
</alert-box>
插槽的 CSS 样式控制
通过 ::slotted()
伪元素可以选择已插入插槽的内容并应用样式。注意:该选择器只能影响顶层插槽元素。
html
<style>
my-component::slotted(h1) {
color: #ff5722;
font-size: 2em;
}
::slotted(p) {
background: #f5f5f5;
}
</style>
动态插槽内容
JavaScript 可以动态操作插槽内容。通过 slotchange
事件可以监听插槽内容变化。
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('插槽内容变化:', e.target.assignedNodes());
});
}
}
customElements.define('dynamic-slot', DynamicSlot);
插槽与 Shadow DOM 的关系
在 Shadow DOM 中,<slot>
是连接外部 Light DOM 和内部 Shadow DOM 的桥梁。浏览器会将 Light DOM 中的内容"分配"到对应的插槽位置。
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>
<!-- 使用示例 -->
<shadow-demo>
主体内容
<div slot="footer">页脚内容</div>
</shadow-demo>
高级插槽模式
多个插槽可以组合使用实现复杂布局。通过命名和嵌套可以构建高度可定制的组件结构。
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>默认按钮</button>
</slot>
</footer>
</div>
</template>
<!-- 使用示例 -->
<advanced-card>
<h2 slot="title">高级卡片</h2>
<p slot="subtitle">使用多个具名插槽</p>
<p>这里是卡片的主要内容区域...</p>
<div slot="actions">
<button>确认</button>
<button>取消</button>
</div>
</advanced-card>
插槽的性能考量
虽然插槽提供了极大的灵活性,但频繁的插槽内容更新可能导致性能问题。在动态场景下,建议使用 MutationObserver
或自定义事件来优化。
javascript
class OptimizedSlot extends HTMLElement {
constructor() {
super();
this._observer = new MutationObserver(() => this._handleChanges());
}
connectedCallback() {
this._observer.observe(this, { childList: true });
}
_handleChanges() {
// 批量处理插槽变化
}
}
浏览器兼容性与 polyfill
现代浏览器普遍支持 <slot>
,但对于旧版浏览器,可以使用 webcomponentsjs polyfill。注意 polyfill 可能无法完全模拟原生插槽的行为。
html
<!-- 加载 polyfill -->
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@2.6.0/webcomponents-bundle.js"></script>
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益,请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:<template>-内容模板
下一篇:<script>-客户端脚本