slot必须配合shadow dom才能工作,需调用this.attachshadow({mode:'open'});仅作用于直系子节点,name属性须严格字符串匹配;::slotted()仅支持单层选择器。

slot 必须配合 Shadow DOM 才能工作
写了 <slot></slot> 却没渲染?大概率是因为没调用 this.attachShadow({ mode: 'open' })。原生 slot 不是 HTML 通用语法,它只在 Web Components 的 Shadow DOM 环境下被浏览器识别和分发。
常见误操作:
- 直接在普通
<div> 里写 <code><p slot="header">标题</p>→ 浏览器当无意义属性丢弃,不报错也不警告 - 自定义元素已注册,但构造函数里漏掉
attachShadow→ 所有传入内容静默消失(不是隐藏,是跳过渲染) - 用了
{ mode: 'closed' }→ 渲染正常,但 JS 无法通过element.shadowRoot访问,调试时容易误判为“slot 没生效” -
slot="Footer"(首字母大写)→ 不匹配name="footer" -
slot="footer "(末尾空格)→ 字符串不等,匹配失败 -
slot="footer-text"(多一个连字符)→ 不等于"footer" ::slotted(h2)::slotted([slot="footer"])::slotted(.btn)-
::slotted(div h2)(后代选择器) -
::slotted(h2:hover)(伪类) -
::slotted(*)(通配符无效)
slot 匹配只认直系子节点,中间不能嵌套
这是最常被忽略的硬性限制:slot 分发只检查自定义元素的**直接子节点**,不递归穿透。
正确写法:<my-card><h2 slot="header">Title</h2></my-card> → <slot name="header"></slot> 能接收到
错误写法:<my-card><div><h2 slot="header">Title</h2></div></my-card> → 整个 <h2></h2> 被丢弃,因为 <div> 是直系子节点,而 <code><h2></h2> 是它的后代
这意味着:组件使用者必须控制传入结构,组件作者无法靠 CSS 或 JS “绕过一层”去匹配内容。
具名 slot 的 name 和 slot 属性必须严格字符串匹配
<slot name="footer"></slot> 只接收 <p slot="footer">©2026</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill7761" title="Article To Html"><img
src="https://img.php.cn/upload/skill/000/000/081/179168408018805.jpg" alt="Article To Html" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill7761" title="Article To Html" class="overflowclass">Article To Html</a>
<p class="overflowclass">文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。</p>
</div>
<a rel="nofollow" href="/xiazai/skill7761" title="Article To Html" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>,其余全部不匹配。大小写、空格、连字符都算不同字符串。
典型失效原因:
默认插槽(无 name)也只接收第一个无 slot 属性的直系子节点;后续同级无属性节点不会塞进第二个空 <slot></slot>,而是直接丢弃。
::slotted() 只支持单层选择器,深层样式得另想办法
::slotted() 是唯一能从 Shadow DOM 内部影响投射内容的样式机制,但它只匹配被分发进来的**直系子元素**,不支持后代选择器或伪类。
可行写法:
无效写法:
如果需要控制嵌套更深的节点,得让外部传入内容自带 class,或在组件内用 slot.assignedNodes() 手动遍历处理——这是真正需要动手的地方,不是加个样式就能解决的。










