slot标签仅在Shadow DOM中生效,必须配合customElements.define()注册自定义元素、调用attachShadow({mode:'open'})、且<slot>写在Shadow DOM内部,三者缺一即静默失效。

slot 标签在普通 HTML 中什么也不做,它只在 Shadow DOM 里生效——没挂 attachShadow(),写了也白写。
为什么 slot 完全没反应?
最常见原因是把它当普通标签用了:直接写在页面里、塞进 <div> 中、或放在未注册的自定义标签内部。浏览器会静默忽略,不报错也不警告。
- 必须用
customElements.define()注册合法自定义元素(如<my-card>),不能对<div>或<p>调用attachShadow(),否则抛出DOMException: This element does not support shadow roots -
attachShadow({ mode: 'open' })必须在constructor或connectedCallback中执行,且只能调一次 -
<slot>必须出现在 Shadow DOM 内部(比如通过shadowRoot.appendChild(template.content.cloneNode(true))插入),不能写在 Light DOM 里
slot 内容不显示,检查直系子节点和 name 匹配
外部内容必须是自定义元素的**直系子元素**,且 slot 属性值与 name 严格相等(区分大小写、首尾空格敏感)。
- ✅ 正确:
<my-card><h2 slot="header">标题</h2></my-card> - ❌ 失效:
<my-card><div><h2 slot="header">标题</h2></div></my-card>(<h2>是孙节点) - ❌ 失效:
<slot name="Header">不匹配<h2 slot="header">(大小写不一致) - ❌ 失效:
<slot name="header">不匹配<h2 slot="header ">(末尾空格) - 没写
name的<slot>默认name="default",只收所有未带slot属性的直系子节点
怎么查 slot 是否真被填满了?
别只看渲染结果;assignedNodes() 在初始化时大概率为空,因为分发还没完成。
立即学习“前端免费学习笔记(深入)”;
- 监听
slotchange事件才是可靠时机:slot.addEventListener('slotchange', () => { console.log(slot.assignedNodes({ flatten: true })); }) -
assignedNodes()默认不展开嵌套结构,必须加{ flatten: true }才能拿到所有最终投射进来的节点(包括 fallback 内容里的节点) -
slotchange不冒泡、不捕获,也不能在shadowRoot上监听,必须绑定到具体<slot>元素上 - Firefox 63 以下不支持
slotchange,需降级用MutationObserver监听slot的childList
真正卡住人的地方,往往不是语法写错,而是层级多了一层、换行符变成了文本节点、或者 attachShadow() 没在正确生命周期里调用——这些都不会报错,但内容就“消失”了。



















