不显示的主因是未启用shadow dom或匹配规则错误:需用customelements.define()注册自定义元素并在constructor/connectedcallback中调用attachshadow,且具名插槽严格区分大小写与空格。

为什么 <slot></slot> 写了但内容不显示
最常见原因是:组件没挂载 Shadow DOM,或者用了不支持 shadow roots 的原生标签(如 <div>、<code><p></p>)。
- 必须用
customElements.define()注册自定义标签,比如<my-card></my-card> - 在
constructor或connectedCallback中调用this.attachShadow({ mode: 'open' }) - 直接把
<slot></slot>写在普通 HTML 里(如<div><slot>fallback</slot></div>)完全无效,浏览器当未知标签处理 - 控制台若报
Failed to execute 'attachShadow' on 'Element': This element does not support shadow roots,说明你试图给非自治元素挂载影子根
slot="xxx" 和 <slot name="xxx"></slot> 匹配不上
具名插槽匹配是严格字符串比对,大小写、空格、连字符一个都不能错。
-
<slot name="header"></slot>只接收<h2 slot="header">标题</h2>,不接收<h2 slot="Header"></h2>或<h2 data-slot="header"></h2> - 多个同名节点(如两个
<p slot="footer"></p>)只会分发第一个,其余被丢弃(无报错) - Vue 用户注意:
<slot name="main"></slot>对应<template v-slot:main></template>,不是v-slot:Main或#Main - Web Components 中不能用绑定表达式写
slot属性值,<p :slot="dynamicName"></p>无效;必须是字面量字符串
内容更新后插槽不刷新
<slot></slot> 分发的是节点引用,不是响应式代理通道。Light DOM 节点内容变了,会立刻反映;但若你靠 JS 动态替换整个节点,就得手动触发重渲染。
- 父级改了
<h2 slot="title">旧标题</h2>的文本为“新标题”,会自动更新——因为它是同一个节点 - 但如果用
el.replaceChild(newH2, oldH2)替换了节点,<slot name="title"></slot>就收不到变化,需监听slotchange事件并调用forceUpdate()或重新 render - 监听方式:
shadowRoot.querySelector('slot[name="title"]').addEventListener('slotchange', handler) -
assignedNodes({ flatten: true })才能拿到所有最终投射进来的节点;不加flatten: true可能返回空数组(只查直系)
IE 兼容和降级处理怎么写
IE 完全不支持 <slot></slot>,也不能调用 attachShadow。降级不能只靠 CSS display:none,得从结构层兜底。
- 服务端或构建时预填充:把
<slot name="header">默认标题</slot>直接替换成实际 HTML 片段,再交给客户端接管 - 运行时检测:
if (!this.attachShadow)则遍历this.childNodes,按slot属性人工插入对应容器(如slot="header"→ 插入到this.querySelector('.header')) - 避免在
<slot></slot>内写交互逻辑(如onclick),事件委托需额外处理 Shadow DOM 边界 - 不要指望插槽 fallback 文本在 IE 里自动显示——它只是 Shadow DOM 内部的占位符,IE 根本不解析
<slot></slot>











