slot内容不显示的根本原因是template标签本身不渲染、不执行、不绑定,它只是待克隆的文档片段;slot生效必须依赖自定义元素+shadow dom,需通过attachshadow并clonenode插入shadowroot。

slot 内容不显示,根本原因不是语法写错了,而是 template 标签本身不渲染、不执行、不绑定 —— 它只是个“待克隆的文档片段”
template 标签不会自动解析 slot
浏览器原生 <template></template> 的 content 是 DocumentFragment,内部的 <slot></slot> 不会被解析,也不会触发任何分发逻辑。哪怕你把它 appendChild 到 body 里,<slot name="header"></slot> 也纯属摆设。
- 常见错误现象:文档示例复制粘贴后页面空白、控制台无报错、DOM 中看不到 slot 内容
- 这不是 Vue 或 React 的
<template></template>,它没有编译器、不参与组件生命周期 - 单独使用
<slot></slot>在<template></template>里,等同于写了一段被忽略的注释
slot 生效必须依赖自定义元素 + Shadow DOM
真正让 <slot></slot> 工作的前提,是该 <template></template> 被某个自定义元素在构造函数中通过 this.attachShadow({ mode: 'open' }) 挂载,并显式调用 cloneNode(true) 插入 shadowRoot。
- 必须同步完成
customElements.define('my-card', MyCard),不能靠外部脚本延迟加载 -
MyCard构造函数里要手动获取template(如document.getElementById('card-tpl')),再shadowRoot.appendChild(template.content.cloneNode(true)) - 禁止用
innerHTML = '<my-card></my-card>'动态插入 —— 这会绕过自定义元素注册时机,导致标签不升级
文档中嵌入可运行示例的硬性要求
用户要的是“复制、粘贴、双击打开就能看效果”,不是教你从零写 Web Component。所以每个示例必须是完整 HTML 页面。
- 示例区块必须用
<pre class="brush:php;toolbar:false;"><code class="html"></code> 包裹,内容含 <code>、<code></code>、<code></code>(含内联 <code><style></style></code> 和必要 polyfill)、<code></code></code></pre> -
<template id="card-tpl"></template>必须有唯一id,所有示例统一用document.getElementById()获取,避免硬编码内容导致维护断裂 - 若需兼容 IE11,
template.content.cloneNode(true)不可用,得降级为注释包裹 +DOMParser解析,且必须加try/catch
最容易被忽略的一点:文档里只展示 <template></template> 片段却不说明“必须配合自定义元素注册”,等于给用户一个没钥匙的锁 —— 看得见,打不开。











