template和slot不能直接使用,必须通过自定义元素+attachShadow显式桥接才能生效;slot仅在Shadow DOM中对直系子节点分发内容,且name属性严格区分大小写与层级。

template + slot 不能直接用,必须配合自定义元素和 Shadow DOM
原生 <template></template> 标签只是存储结构的容器,它本身不渲染、不挂载、不解析 <slot></slot>。你写好 <template id="card"><slot name="title"></slot></template>,然后直接在页面里放 <my-card><h2 slot="title">Hello</h2></my-card> —— 这不会生效,浏览器根本不知道 my-card 是什么。
真正起作用的链条只有这一条:<template></template> 存结构 → 自定义元素类(extends HTMLElement)→ this.attachShadow({ mode: 'open' }) → shadowRoot.appendChild(tpl.content.cloneNode(true)) → 插槽才开始匹配和分配。
常见错误现象:
- 插槽内容完全不显示,控制台也无报错(原因:没注册自定义元素,或没调用
attachShadow) - 默认插槽显示了,但具名插槽(
slot="header")始终 fallback 到默认内容(原因:父节点不是直系子节点,中间有空格/换行/文本节点) - 插槽内容渲染了,但样式失效(原因:CSS 没写在 shadowRoot 内,或没加
:host/::slotted()选择器)
具名插槽 name 必须字面量全等,且子节点必须是直系
<slot name="header"></slot> 只会匹配 <h2 slot="header"></h2>,不匹配 <h2 slot="HEADER"></h2> 或 <h2 slot=" header "></h2>。大小写、空格、引号类型(单/双)都必须严格一致。
更重要的是:插槽内容必须是自定义元素的**直系子节点**。下面这三种写法都会导致 assignedNodes() 返回空数组,插槽 fallback:
-
<my-card>↵ <h2 slot="header">Title</h2>↵</my-card>(换行符和缩进空格算文本节点) -
<my-card><div><h2 slot="header">Title</h2></div></my-card>(<h2></h2>不是直系) -
<my-card><!-- comment --><h2 slot="header">Title</h2></my-card>(注释也是节点)
安全写法只有一种:<my-card><h2 slot="header">Title</h2></my-card>,中间不能有任何其他节点。
动态插槽内容更新需要手动触发,不是响应式的
Shadow DOM 的插槽分配是静态的:在元素插入时做一次 assign,之后子节点变化(比如你用 JS 改了 textContent 或增删子元素),插槽不会自动重分配。这意味着:
- 你不能靠
v-if或v-for控制插槽内容显隐(Vue 场景下需用v-slot配合响应式数据) - 纯 HTML+JS 场景下,若要动态替换插槽内容,得手动操作:
el.querySelector('[slot="header"]').remove(),再el.insertAdjacentElement('afterbegin', newHeader) - 如果插槽内容来自异步加载(如 fetch 后插入),记得等节点 append 完再检查
el.shadowRoot.querySelector('slot').assignedNodes(),否则可能为空
Laravel Blade / Vue / Angular 的插槽逻辑完全不同,别混用概念
很多人卡在“为什么我在 Laravel 里写了 <x-card><h2 slot="title"></h2></x-card> 却不生效”,是因为 Blade 的 slot 是服务端模板编译机制,和 HTML 原生 <slot></slot> 毫无关系。同理:
- Vue 的
<slot></slot>是编译期指令,运行时由 Vue 渲染器接管,不依赖 Shadow DOM - Angular 没有原生插槽语法,
ng-content是它的替代方案,行为类似但 API 和生命周期不同 - Blade 的
@slot是 PHP 层字符串拼接,{!! $slot !!}是绕过转义,和 DOM 分配无关
跨框架时最容易踩的坑,就是把一个体系的插槽写法抄到另一个体系里,结果既不报错也不渲染——因为根本没走到对应解析逻辑中。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











