js实现slot
实现 Slot 的基本概念
Slot 是 Web Components 技术的一部分,允许在自定义元素中插入外部内容。它类似于 Vue 或 React 中的插槽机制,用于内容分发。
基本 Slot 用法
在自定义元素的模板中使用 <slot> 标签定义插槽位置:
<template id="my-template">
<div>
<slot name="header">默认头部内容</slot>
<slot>默认内容</slot>
<slot name="footer">默认底部内容</slot>
</div>
</template>
创建带 Slot 的自定义元素
class MyElement extends HTMLElement {
constructor() {
super();
const template = document.getElementById('my-template');
const templateContent = template.content;
this.attachShadow({mode: 'open'}).appendChild(templateContent.cloneNode(true));
}
}
customElements.define('my-element', MyElement);
使用命名 Slot
在自定义元素实例中指定插槽内容:
<my-element>
<h1 slot="header">自定义头部</h1>
<p>这是主要内容</p>
<div slot="footer">自定义底部</div>
</my-element>
动态修改 Slot 内容
通过 JavaScript 动态更新插槽内容:
const element = document.querySelector('my-element');
const newHeader = document.createElement('h2');
newHeader.textContent = '新标题';
newHeader.slot = 'header';
element.appendChild(newHeader);
监听 Slot 变化
使用 slotchange 事件监听插槽内容变化:
const slot = shadowRoot.querySelector('slot[name="header"]');
slot.addEventListener('slotchange', (e) => {
console.log('Header slot 内容变化:', e.target.assignedNodes());
});
获取已分配节点
访问插槽中实际分配的内容节点:
const headerSlot = shadowRoot.querySelector('slot[name="header"]');
const headerNodes = headerSlot.assignedNodes();
console.log('Header 内容:', headerNodes);
多 Slot 回退机制
当没有提供插槽内容时显示默认内容:
<slot name="optional">
<p>当没有提供 optional 内容时显示这段文本</p>
</slot>
Slot 的 CSS 样式
为插槽内容添加样式:
::slotted(h1) {
color: blue;
font-size: 2em;
}
/* 仅对具名插槽的内容生效 */
::slotted([slot="header"]) {
border-bottom: 1px solid #ccc;
}
Shadow DOM 与 Light DOM 的区别
Slot 内容来自 Light DOM,但显示在 Shadow DOM 中。样式隔离规则需要注意:
- Shadow DOM 中的样式不会影响 Light DOM
- 使用
::slotted()可以有限地样式化插槽内容 - 插槽内容保留其原有的 DOM 结构
高级 Slot 模式
实现条件性插槽显示:

const mainSlot = shadowRoot.querySelector('slot');
mainSlot.hidden = !this.hasAttribute('show-main');
浏览器兼容性提示
大多数现代浏览器支持 Slot API,但旧版浏览器可能需要 polyfill。可以考虑使用 @webcomponents/webcomponentsjs 等库来提供向后兼容支持。






