slot是Web Components中Shadow DOM内生效的内容分发原生机制,必须通过attachShadow创建影子根并将slot模板插入其中,且外部内容须为自定义元素的直系子节点才能正确投射。

slot 标签是 Web Components 中内容分发的原生机制,不是 Vue 或 React 的语法糖——它在 Shadow DOM 里起作用,且不依赖任何框架。
为什么直接写 slot 没反应?
因为 slot 只在 Shadow DOM 内部生效,裸露在普通 HTML 中不会做任何事。常见错误是把 <slot></slot> 直接写在页面里,或者写在未启用 Shadow DOM 的自定义元素中。
- 必须先调用
this.attachShadow({ mode: 'open' })创建 Shadow Root - 必须把含
slot的模板(如<template>)显式插入到 Shadow Root 中 - 外部传入的内容必须是该自定义元素的**直系子节点**,不能隔着 wrapper 元素(除非你手动转发)
slot 的 name 属性怎么匹配内容?
匹配靠的是元素上的 slot 属性值,而不是标签名或结构层级。它只看字符串是否完全一致,区分大小写,且不支持通配符。
- 子组件中:
<slot name="header"></slot> - 父组件中:
<h1 slot="header">Title</h1>✅ 匹配成功 - 父组件中:
<div><h1 slot="header">Title</h1></div>❌ 不匹配——h1不是自定义元素的直系子节点 - 没写
name的slot默认叫"default",对应所有未带slot属性的直系子节点
如何检查插槽有没有被正确填充?
别只看渲染结果;Shadow DOM 的内容分发是声明式、静态的,但实际投射状态得靠 API 查。
立即学习“前端免费学习笔记(深入)”;
- 在自定义元素内部,调用
this.shadowRoot.querySelector('slot').assignedNodes()—— 返回当前被投射进来的节点列表(含文本节点) - 如果返回空数组,说明没内容被分配进来,大概率是父子节点关系不对或
slot属性拼错 -
assignedElements()只返回元素节点,忽略文本节点,适合需要过滤纯文本的场景 - 注意:这些方法返回的是实时快照,不是响应式引用;DOM 变更后需重新调用
默认内容和 fallback 怎么共存?
slot 标签内部的 HTML 是 fallback 内容,仅当没有节点被分配进来时才显示。但它不是“兜底渲染”,而是“无分配时的占位”。
-
<slot><p>Loading...</p></slot>:只有当父组件没传任何直系子节点时,才显示Loading... - 一旦有任意节点被分配(哪怕只是个空文本节点),fallback 就不会出现
- 想实现“有内容就显示内容,没内容就显示 fallback,但还要支持 CSS 控制显隐”,得额外加逻辑判断,不能只靠
slot自身
真正容易被忽略的是:slot 的内容分发发生在浏览器渲染管线早期,它不触发 Vue 的响应式更新,也不参与 React 的 reconciler;如果你在框架组件里嵌套原生 slot,得自己处理好生命周期同步和事件代理边界。



















