默认内容仅在父组件完全未传任何节点(含空格、换行、注释)时渲染,assignednodes()非空即失效;具名插槽需静态name属性匹配,动态绑定不支持默认内容,作用域插槽默认内容无法访问子组件数据。

<slot></slot> 的默认内容只在父组件「完全没传任何节点」时才显示,连空格、换行符、注释都算“已传内容”,默认内容立刻失效。
为什么写了默认内容却从不渲染?
浏览器对 <slot></slot> 的 fallback 判断极其严格:只要父元素的子节点列表(this.shadowRoot.querySelector('slot').assignedNodes())非空,默认内容就跳过。常见误判场景:
- 父组件写成
<my-comp>\n </my-comp>—— 换行 + 空格 →assignedNodes()返回长度为 2 的数组 → 默认内容不显示 - 用
<div><my-comp></my-comp></div>包裹,但子组件模板里漏了<slot></slot>标签 → 内容被静默丢弃,不是 fallback 失效,是根本没插槽接收 - 父组件用了
v-if="false"包裹插槽内容 → 节点未创建,assignedNodes()为空 → 默认内容正常显示;但换成v-show,节点仍在 DOM 中 → 默认内容不显示
Vue 中 <slot></slot> 默认内容的写法与限制
Vue 的 <slot></slot> 默认内容逻辑和原生 Web Components 一致,但编译期会做静态分析:
- 子组件中直接写:
<slot>Loading...</slot>—— 最简有效方式 - 具名插槽也支持默认内容:
<slot name="header"><h2>Default Header</h2></slot> - 动态插槽名不支持默认内容:
<slot :name="slotName"></slot>❌ 不生效;必须用静态name属性 - 作用域插槽的默认内容无法访问作用域数据,因为作用域变量仅在父组件插槽内容求值时注入
怎么验证是否真“没传内容”?
别靠肉眼判断页面是否空白,得查真实分发状态:
- 在自定义元素中,用
this.shadowRoot.querySelector('slot').assignedNodes({ flatten: true })查返回数组长度 - 在 Vue 组件的
mounted钩子中,通过this.$refs.slotRef.assignedNodes()(需给<slot></slot>加ref)确认 - Chrome DevTools 中右键 slot 元素 → “Break on” → “attribute modifications”,看
slot是否被动态加了name或其他属性干扰匹配 - 注意:uni-app 的 NVue 渲染模式下不支持具名 slot,此时所有
name属性都会被忽略,导致本该回退的具名插槽直接无内容
真正卡住调试的,从来不是语法写错,而是把“看着空”当“真的空”——空格、换行、v-show、shadow DOM 分发时机、平台兼容性,每个都可能让默认内容彻底消失。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











