js实现slot
实现 Slot 的基本概念
Slot 是 Web 组件中用于内容分发的机制,允许父组件向子组件传递内容。在原生 HTML 和 JavaScript 中,可以通过 <slot> 元素实现类似 Vue 或 React 中的插槽功能。
使用 Shadow DOM 创建 Slot
Shadow DOM 允许将组件的内部结构与外部 DOM 隔离,同时通过 <slot> 元素实现内容分发。
<!DOCTYPE html>
<html>
<head>
<title>Slot Example</title>
</head>
<body>
<custom-element>
<p>This content will be slotted</p>
</custom-element>
<script>
class CustomElement extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
shadow.innerHTML = `
<div>
<slot></slot>
</div>
`;
}
}
customElements.define('custom-element', CustomElement);
</script>
</body>
</html>
命名 Slot 的实现
命名 Slot 允许将特定内容分发到子组件的指定位置。

<custom-element>
<p slot="header">Header Content</p>
<p slot="footer">Footer Content</p>
</custom-element>
<script>
class CustomElement extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
shadow.innerHTML = `
<div>
<slot name="header"></slot>
<slot name="footer"></slot>
</div>
`;
}
}
customElements.define('custom-element', CustomElement);
</script>
默认 Slot 和 Fallback 内容
如果未提供分发内容,Slot 可以显示默认的 Fallback 内容。
<custom-element></custom-element>
<script>
class CustomElement extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
shadow.innerHTML = `
<div>
<slot>Default Content</slot>
</div>
`;
}
}
customElements.define('custom-element', CustomElement);
</script>
动态 Slot 内容分发
通过 JavaScript 动态操作 Slot 内容。

<custom-element id="dynamic-slot"></custom-element>
<script>
class CustomElement extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
shadow.innerHTML = `
<div>
<slot name="dynamic"></slot>
</div>
`;
}
}
customElements.define('custom-element', CustomElement);
const element = document.getElementById('dynamic-slot');
const content = document.createElement('p');
content.textContent = 'Dynamic Content';
content.slot = 'dynamic';
element.appendChild(content);
</script>
Slotchange 事件监听
通过 slotchange 事件监听 Slot 内容的变化。
<custom-element>
<p slot="changeable">Changeable Content</p>
</custom-element>
<script>
class CustomElement extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
shadow.innerHTML = `
<div>
<slot name="changeable"></slot>
</div>
`;
const slot = shadow.querySelector('slot');
slot.addEventListener('slotchange', (e) => {
console.log('Slot content changed:', e.target.assignedNodes());
});
}
}
customElements.define('custom-element', CustomElement);
</script>
多 Slot 内容分发
在单个组件中使用多个 Slot 分发不同内容。
<custom-element>
<p slot="title">Title</p>
<p slot="description">Description</p>
</custom-element>
<script>
class CustomElement extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
shadow.innerHTML = `
<div>
<h1><slot name="title"></slot></h1>
<p><slot name="description"></slot></p>
</div>
`;
}
}
customElements.define('custom-element', CustomElement);
</script>
使用模板和 Slot
结合 <template> 和 <slot> 实现更灵活的组件结构。
<template id="templated-element">
<style>
div { border: 1px solid #ccc; padding: 10px; }
</style>
<div>
<slot name="header"></slot>
<slot></slot>
</div>
</template>
<custom-template>
<h1 slot="header">Header</h1>
<p>Default slot content</p>
</custom-template>
<script>
class CustomTemplate extends HTMLElement {
constructor() {
super();
const template = document.getElementById('templated-element');
const shadow = this.attachShadow({ mode: 'open' });
shadow.appendChild(template.content.cloneNode(true));
}
}
customElements.define('custom-template', CustomTemplate);
</script>
注意事项
- Shadow DOM 的
mode设置为open时,外部 JavaScript 可以访问组件的 Shadow DOM。 - 命名 Slot 必须与分发内容的
slot属性匹配。 slotchange事件仅在 Slot 内容变化时触发,不包括初始渲染。






