template标签不参与渲染,必须手动克隆并插入Shadow DOM才能激活slot分发;slot仅在已attachShadow的自定义元素内生效,否则被当作文本忽略。

template 标签本身不参与渲染,也不能直接和 slot 联动实现“自动分发”——必须靠 JavaScript 手动克隆 + 插入,或配合自定义元素 + Shadow DOM 才能真正完成动态内容分发。
为什么直接写 <template><slot></slot></template> 不生效
浏览器把 template 当作纯离线容器,里面的内容不会解析、不触发样式、不执行脚本;slot 又只在已挂载 Shadow DOM 的自定义元素内部起作用。二者叠加却不初始化 Shadow DOM,结果就是:slot 被当作文本忽略,内容被丢弃,控制台也无报错。
-
template.content是DocumentFragment,不能直接appendChild到 document —— 得用importNode()或cloneNode(true) - 写了
<slot name="header"></slot>但没调用this.attachShadow()?那它只是个无意义的标签字符串 - 模板里有
<img src="...">?它不会加载,除非你克隆后插入到文档流中
template + 自定义元素 + slot 的最小可行组合
想让模板内容“活”起来并支持插槽分发,必须走 Web Components 路线:声明模板 → 定义自定义元素 → 在构造函数中 attachShadow → 把模板内容注入 shadowRoot → 外部用 slot 属性传内容。
- 模板定义要带 id:
<template id="card-tmpl"><header><slot name="header">Default</slot></header><main><slot>Body</slot></main></template> - JS 中取模板:
const tmpl = document.getElementById('card-tmpl');,然后shadowRoot.appendChild(tmpl.content.cloneNode(true)); - 不要在
connectedCallback里重复 attachShadow(会报错),也不要在每次更新时清空重建 shadowRoot(破坏节点复用)
具名 slot 匹配失败时内容“消失”的真实原因
不是 bug,是规范行为:匹配完全依赖字符串精确一致。哪怕多一个空格、大小写错一位、连字符位置不对,内容就进不了插槽,也不会 fallback(除非插槽内写了默认文本且完全没匹配节点)。
-
<slot name="aside">侧边栏</slot>只接收<div slot="aside">...</div>,不接收<div slot="Aside">或<div slot=" aside"> - 两个
<h3 slot="title">A</h3><h3 slot="title">B</h3>?只有 A 出现在插槽里,B 被静默丢弃 - 空节点也会阻断 fallback:
<div slot="footer"></div>占位了插槽,但没内容,此时<slot name="footer">默认页脚</slot>不会显示
别指望 ::slotted(*) 做复杂样式
它只能选一层简单选择器,无法处理伪类、后代选择器或深层嵌套,而且优先级低,容易被 light DOM 原有样式覆盖。
立即学习“前端免费学习笔记(深入)”;
- ✅
::slotted(.btn)可以设置颜色 - ❌
::slotted(.btn:hover)、::slotted(div .text)全部无效 - 更可靠的方式是透传 CSS 自定义属性:
:host { --text-color: #333; },再在插槽内容里用color: var(--text-color);
attachShadow 得在构造函数里执行,cloneNode(true) 得在 shadowRoot 创建之后调用——漏掉任一环,内容就“不见了”,还查不出错。



















