slot不是原生html元素,而是web components中配合shadow dom使用的语义化占位符;必须在自定义元素中调用attachshadow后才生效,仅在shadowroot内有效,且name属性区分大小写、不支持动态绑定。

slot 不是原生 HTML 元素,而是 Web Components 规范中的 DOM 插入机制
它本身不是像 <div> 或 <code><p></p> 那样的独立 HTML 标签,而是一个语义化占位符,只在自定义元素(customElements.define 创建的组件)内部配合 <shadowroot></shadowroot> 使用才生效。直接写 <slot></slot> 在普通 HTML 页面里不会产生任何插槽行为,浏览器会把它当做一个未知的、无意义的空标签处理。
slot 必须配合 Shadow DOM 才能起作用
没有 attachShadow,<slot></slot> 就只是摆设。常见错误是写了 <slot name="header"></slot> 却没调用 element.attachShadow({ mode: 'open' }),结果内容完全不渲染。
- 必须在自定义元素构造函数中调用
this.attachShadow -
<slot></slot>只能出现在shadowRoot内部,不能放在 light DOM 中“提前声明” - 父级传入的内容(light DOM)由浏览器自动匹配到对应
<slot></slot>,无需手动调用 API
slot 的 name 属性区分大小写,且不支持动态绑定
name 是纯字符串匹配,<slot name="Footer"></slot> 和 <p slot="footer"></p> 不会配对——大小写不一致就失效。另外,slot 属性值不能是表达式或响应式变量,比如 <p :slot="dynamicName"></p>(Vue 语法)或 <p slot="{{name}}"></p> 都无效,浏览器只认静态字符串。
- 合法:
<h2 slot="title">Hello</h2> - 非法:
<h2 slot="Title">Hello</h2>(大小写错) - 非法:
<h2 slot="{title}">Hello</h2>(JS 表达式不被解析)
默认 slot 和具名 slot 的 fallback 行为容易混淆
没指定 name 的 <slot></slot> 是默认插槽,它会接收所有未被具名 slot 消费的 light DOM 节点。但如果你写了多个无 name 的 <slot></slot>,只有第一个生效,其余被忽略——这点和 Vue 的 <slot></slot> 行为不同,容易误以为能“分流”内容。
- 一个组件里只应有一个匿名
<slot></slot> - 具名
<slot name="xxx"></slot>只匹配slot="xxx"的节点,不匹配其他内容 - 没被任何
<slot></slot>匹配的 light DOM 节点会被丢弃(除非用了<slot></slot>默认兜底)
<slot></slot> 自己变灵活。











