slot 只在 shadow dom 中生效,需同时满足定义自定义元素、调用 attachshadow()、将 slot 写入 shadow dom 三前提;内容匹配依赖 slot 属性值与具名 slot 的精确一致,且不报错仅静默失效。

slot 不是普通 HTML 标签,它只在 Shadow DOM 内生效,且必须配合自定义元素使用;单独写 <slot></slot> 在普通页面里不会起任何作用。
如何让 slot 真正工作起来
它依赖三个硬性前提:定义了自定义元素、调用了 attachShadow()、把 slot 写在 Shadow DOM 里。缺一不可。
- 没调
attachShadow()→slot被当成普通未知标签,不解析、不投射 - 把
slot写在 Light DOM(比如直接丢在里)→ 完全无效,浏览器忽略 - 自定义元素的
mode: 'closed'→slot.assignedNodes()返回空数组,但内容仍会正常渲染
默认插槽和具名插槽的匹配规则
匹配不是“查找替换”,而是基于 Light DOM 子元素是否带 slot 属性、以及属性值是否与 <slot name="xxx"></slot> 一致。
- 外部写
<my-card><h2 slot="title">Hi</h2> <p>Body</p><div class="aritcle_card flexRow artxards"> <div class="artcardd flexRow"> <a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill4293" title="Doc To HTML"><img src="https://img.php.cn/upload/skill/000/000/081/178998486916110.jpg" alt="Doc To HTML" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a> <div class="aritcle_card_info flexColumn"> <a rel="nofollow" href="/xiazai/skill4293" title="Doc To HTML" class="overflowclass">Doc To HTML</a> <p class="overflowclass">使用 MinerU 文档处理引擎将 Word 文档(.doc、.docx)转换为保留结构和格式的干净 HTML。</p> </div> <a rel="nofollow" href="/xiazai/skill4293" title="Doc To HTML" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div></my-card>→ 只有<h2></h2>进入<slot name="title"></slot>,<p></p>进入第一个无name的<slot></slot> - 多个同名
<slot name="item"></slot>→ 每个都会收到一份匹配节点副本(不是分片,是完整复制) - 没写
slot属性的内容,又没找到默认<slot></slot>→ 节点保留在 Light DOM 中,但不渲染
为什么拿不到 slot 里的文本或数据
slot 本身不提供 value、textContent 或类似 React 的 props.children;它只负责“显示位置”,不负责“提取内容”。
- 想读文本?得监听
slotchange事件,再调slot.assignedNodes({ flatten: true })遍历找Text节点 - 想取子元素的
data-id?要手动查slot.assignedElements(),再逐个访问.dataset.id -
::slotted(*)伪类只能样式化已投射内容,不能触发 JS 逻辑或读取属性
常见报错和静默失败场景
很多问题根本不会抛错,只是内容不出现,排查时容易绕远路。
-
Uncaught TypeError: Cannot read property 'assignedNodes' of null→ 忘了用shadowRoot.querySelector('slot'),直接对 Light DOM 里的元素调用了 - 内容渲染了,但
assignedNodes()返回空 → 检查attachShadow()的mode是否为'closed' - 嵌套自定义元素内部的内容没被投射 →
slot只匹配 Light DOM 直系子元素,不穿透任何封装层 -
slot="header"写成slot="Header"→name属性区分大小写,匹配失败即丢弃
真正麻烦的不是语法,而是它不报错、不警告、不提示——内容“消失”时,你得同时检查自定义元素定义、Shadow DOM 构建时机、Light DOM 结构、属性拼写,四者缺一不可。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










