slot是Web Components中唯一原生支持内容分发的机制,必须在Shadow DOM内通过attachShadow创建并配对name属性才能生效,未匹配内容会被丢弃。

slot 标签是 Web Components 中唯一原生支持内容分发(content distribution)的机制,它不依赖框架、不运行在 JavaScript 层,而是由浏览器 DOM 引擎直接解析和投射。如果你正在用 attachShadow 构建自定义元素,却发现子元素没渲染进去——大概率是漏了 slot 或没配对好 slot 的 name 属性。
默认插槽为什么没显示子节点?
Shadow DOM 默认隔离外部内容,slot 是唯一“开口”。没有 <slot></slot>,父元素传入的任何子节点都会被丢弃(不报错,但不可见)。
- 必须在
shadowRoot内部显式写一个<slot></slot>,才能接收所有未带slot属性的子节点 - 多个无名
<slot></slot>会按顺序接收内容:第一个<slot></slot>接收前几个子节点,第二个接后续——但实际中几乎不用,容易混乱 - 如果组件模板里写了
<slot>默认文案</slot>,当外部没传内容时,就显示“默认文案”;但注意:只要外部有任意子节点(哪怕只是空格文本节点),默认文案就会被完全替换
具名插槽 name 不匹配的典型表现
常见错误是 <slot name="header"></slot> 和 <h1 slot="header">标题</h1> 看似对得上,但页面仍空白——原因往往出在大小写、空格或 Shadow DOM 插入时机。
-
name值严格区分大小写:slot="Header"≠<slot name="header"></slot> - 父元素子节点必须在
customElements.define之后、且该自定义元素已插入 DOM 才能被正确投射;动态添加子节点需手动调用element.assignedSlot检查是否绑定成功 - 不要在
slot标签内嵌套其他slot,浏览器不支持嵌套插槽投射
如何调试 slot 内容是否被正确分发?
不能靠肉眼检查 DOM 结构——Shadow DOM 里的 slot 节点本身不渲染内容,真正显示的是其 assignedNodes() 返回的节点集合。
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
立即学习“前端免费学习笔记(深入)”;
- 在 DevTools 中选中自定义元素 → 切到 “Elements” 面板 → 展开
#shadow-root→ 找到<slot></slot>→ 右键 “Break on” → “attribute modifications”,可捕获投射变化 - 运行
document.querySelector('my-card').shadowRoot.querySelector('slot').assignedNodes(),返回空数组说明没内容投射进来 - 用
console.dir(slotElement)查看assignedElements和assignedNodes,确认节点类型(Text节点常被忽略,但它也算内容)
slot 与 Vue/React 插槽的本质区别在哪?
Web Components 的 slot 是声明式、编译期行为,而 Vue 的 <slot></slot> 是运行时虚拟 DOM diff 的产物。这意味着:
- 原生
slot不受 JS 框架生命周期影响,即使组件没挂载,只要 DOM 存在就能投射 - Vue 的
slot本质是函数或作用域对象,可以传递数据;原生slot只能分发静态 DOM 片段,无法直接传值(要传数据得靠属性或事件) - 跨框架互操作时,只有原生
slot能被所有框架识别;Vue 组件内部的<slot></slot>对纯 HTML 使用者完全不可见
最容易被忽略的一点:slot 分发发生在浏览器布局计算之前,但 assignedNodes() 返回的节点仍处于 Light DOM,样式穿透需用 ::slotted(*),且仅支持简单选择器——复杂伪类(如 ::slotted(.btn:hover))无效。


















