slot标签仅在Shadow DOM中生效,需满足三个条件:自定义元素调用attachShadow、slot位于Shadow Root内、外部内容为直系子节点;具名插槽name严格区分大小写;默认插槽唯一且无name;name不支持动态绑定。

slot 标签本身不渲染,只在 Shadow DOM 中生效
直接在普通 HTML 文件里写 或 ,页面上什么都不会出现——浏览器把它当未知标签忽略,不报错也不警告。它不是占位符,也不是模板语法糖,只有满足三个硬性条件才会工作:
- 自定义元素类中调用
this.attachShadow({ mode: 'open' }) -
必须出现在 Shadow Root 内部的模板中(比如通过shadowRoot.appendChild(template.content.cloneNode(true))插入) - 外部传入的内容必须是该自定义元素的**直系子节点**,例如:
✅;而Title
❌Title
具名插槽的 name 属性严格区分大小写
匹配失败八成是因为大小写不对。浏览器执行的是精确字符串比对,不自动转小写、不 fallback、不模糊匹配:
-
只接收 -
会被丢进默认插槽(如果存在),或静默丢弃(如果没定义默认插槽) - 主流浏览器(Chrome/Firefox/Safari/Edge)行为完全一致,这不是 bug,是 HTML 规范强制要求
默认插槽只能有一个,且不能带 name
一个组件内可以有多个具名插槽,但最多只能有一个无 name 属性的 。它的作用很明确:收容所有未被具名插槽匹配的直系子节点。
- 比如子组件含
、、,那么:→ 进第一个插槽→ 进第三个插槽或正文
→ 全部进中间那个默认插槽 - 重复声明同名插槽(如两个
)允许,但内容只被第一个捕获,后续同名插槽保持空 - 没声明任何
?所有传入内容都会被丢弃,DOM 中不可见也不可访问
name 不支持动态绑定,只能是静态字面量
name 是纯 HTML 属性,不是响应式字段。写成 或 都无效——解析阶段就当作字面量处理。
- Vue 模板中若没用
v-bind:name,生成的 DOM 就是(引号里真的是这 11 个字母) - 真正有效的只有编译/运行时已确定的字面量:
、 - 想实现“动态插槽名”,得靠 JS 手动控制:比如根据条件渲染多个固定
/,再配合v-if切换显隐
最容易被忽略的点是:slot 分发不触发重排重绘,也不抛异常,错配就静默丢弃。调试时别只盯着渲染结果,要立刻查 slotElement.assignedNodes() 返回是否为空——但注意,必须等 slotchange 事件触发后调用才可靠,connectedCallback 里直接查大概率是空数组。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











