默认插槽是未指定name属性的<slot>,用于接收父组件传入的未匹配具名插槽的所有内容;必须在封装卡片、模态框等包裹型组件时使用,子组件模板中须显式声明<slot>,父组件内容才会被正确渲染,否则静默丢失。

slot默认插槽是什么,什么时候必须用它
默认插槽就是没加 name 属性的 <slot>,它接收组件内所有未被具名插槽匹配的子节点。你写自定义组件时,如果想让使用者像写普通 HTML 一样直接塞内容进去(比如 <my-card>这里是标题和描述</my-card>),那就得靠它——不是可选,是必需。
常见场景:封装卡片、模态框、按钮容器这类“包裹型”组件;也常和具名插槽共存,比如一个 <slot> 放主体内容,再配个 <slot name="footer"> 放底部操作。
怎么写才能让 slot 显示出来
两头都要对得上:父组件里写的内容,得被子组件模板里的 <slot> 接住。漏掉任意一端,内容就“消失”了——不是报错,是静默不渲染,最容易误以为代码没生效。
- 子组件(如
MyCard.vue或纯 HTML 自定义元素)模板中必须显式写出<slot></slot>,不能只靠 CSS 或 div 包裹替代 - 父组件中写在标签内的文本、HTML 元素、甚至其他组件,只要没被
slot="xxx"指定,都会落到默认插槽里 - 如果子组件模板里没写
<slot>,哪怕父组件写了内容,也完全不会出现在 DOM 中
默认插槽内容为空时怎么兜底
用户可能什么也不传,这时候页面就空一块。用 <slot> 的默认内容机制最稳妥——写在 <slot> 标签内部的 HTML,仅当外部没传内容时才显示。
立即学习“前端免费学习笔记(深入)”;
<!-- 子组件模板 --> <div class="card"> <slot>暂无内容</slot> </div>
注意:暂无内容 是纯静态 fallback,不支持绑定响应式数据或指令(比如 {{ msg }} 或 v-if 在这里无效)。真要动态兜底,得用 JavaScript 判断 $slots.default 是否存在(Vue)或 assignedNodes()(原生 Web Components)。
为什么 slot 里的事件监听失效或作用域不对
默认插槽的内容是在父组件作用域中编译的,所以事件处理器、v-model、插值表达式都按父组件逻辑执行。这不是 bug,是设计如此——但容易让人困惑“为什么子组件里绑不了 click?”
- 想在子组件内统一处理插槽内容的点击?不行。得由父组件传入事件回调,比如
@click="handleClick"写在父组件的插槽内容上 - 想给插槽内容加样式?CSS 作用域隔离下,子组件的
<style scoped>默认影响不到插槽内容,得用:deep(.xxx)(Vue)或::slotted(*)(Shadow DOM) - 插槽内容里用了
v-for或v-if?没问题,它完全属于父组件的编译上下文
真正容易被忽略的是:插槽不是“子组件的一部分”,它只是被“投射”进去的片段。它的生命周期、响应性、作用域,全由父组件决定。



















