slot的name属性是具名插槽生效的唯一开关,必须严格字符串匹配(大小写、空格、连字符均敏感),仅对直系子元素生效,不支持动态值,且与默认插槽严格分区无回退。

slot 的 name 属性不是“可选优化项”,而是具名插槽生效的唯一开关;不写、写错、动态拼接,都会导致内容静默丢失——它不报错,只沉默。
name 属性必须完全匹配 slot 属性值
匹配是纯字符串比对,大小写、空格、连字符全算数。浏览器不会做任何转换或容错:
-
<slot name="header"></slot>只接收<h1 slot="header">标题</h1> -
<h1 slot="Header"></h1>、<h1 slot="header "></h1>、<h1 slot="header-2"></h1>全部不匹配,内容进默认插槽(如果存在)或直接丢弃 - 多个同名
<slot name="item"></slot>时,只有第一个能分发到节点;后续插槽保持空,不会复制内容
slot 属性只对直系子元素生效
这是最容易被忽略的 DOM 结构约束:外部传入的内容必须是自定义元素的**直接子节点**,否则 slot 属性会被完全忽略:
- ✅ 正确:
<my-card><h2 slot="title">Hello</h2></my-card> - ❌ 无效:
<my-card><div><h2 slot="title">Hello</h2></div></my-card>——<h2></h2>是孙节点,不参与分发 - 调试建议:检查
document.querySelector('my-card').shadowRoot.querySelector('slot[name="title"]').assignedNodes()是否为空数组
name 属性不支持运行时动态值
原生 <slot></slot> 的 name 是静态属性,不能绑定变量、表达式或模板语法:
- ❌ 无效:
<slot :name="headerName"></slot>(Vue 模板中未用v-bind:name时,实际解析为字面量name="headerName") - ❌ 无效:
<slot name="{{ name }}"></slot>(模板引擎未编译前只是文本) - ✅ 唯一有效方式:写死字符串,如
<slot name="sidebar"></slot>或通过 JS 手动设置el.setAttribute('slot', 'sidebar') - 注意:Vue 的
v-slot是模拟机制,但若组件底层用了 Shadow DOM,仍受此限制
具名插槽与默认插槽共存时的分发逻辑
它们不是“备选关系”,而是严格分区的独立通道:
- 带
slot="xxx"的节点,只尝试匹配<slot name="xxx"></slot>,**永远不会 fallback 到默认插槽** - 没写
slot属性的节点(如<p>正文</p>),只进第一个无name的<slot></slot>,其余匿名插槽被跳过 -
<slot name="aside">侧边栏默认内容</slot>中的 fallback 文本,仅在assignedNodes().length === 0时显示;哪怕有一个空的<div slot="aside"></div>,fallback 也不会出现
真正难调试的从来不是语法写错,而是内容“看不见却没报错”——这时候优先查 assignedNodes() 返回值、确认节点层级、核对每一个字符是否完全一致。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











