本节摘要:组件除了接收数据,还常要"装进任意内容"。Vue 用插槽(slot)定义可变空位,React 用 children 表达同一思想。具名插槽、默认插槽、作用域插槽三件套讲清后,你就能写出规整外壳又能被"塞内容"的通配组件。
本节阅读目标
阅读完本节,你应当能够:
props 适合传"结构化数据",但有时候你希望组件只是一个容器——里面装什么由使用方决定。比如一个卡片组件,标题是一样的外壳,内容却因人而异。若把内容全做成 props,类型会爆炸;这正是插槽/children 解决的问题。
默认插槽承接无名内容,具名插槽对应多个位:
<template> <div class="panel"> <header><slot name="title">默认标题</slot></header> <div class="body"><slot>默认内容</slot></div> </div> </template>
使用方在引入处往里装:
<Panel> <template #title>本周热销</template> 给你一段正文内容,可以是任意结构。 </Panel>
#title 指定具名插槽,未命名内容自动落入默认插槽。这比硬塞 props 干净得多——结构由调用方自由发挥,外壳保持规整。
有时主组件算出数据,希望插槽内容去用这份数据。作用域插槽把内部变量传给插槽作用域:
<template> <section> <slot :user="user" /> </section> </template> <script setup> import { ref } from 'vue'; const user = ref({ name: '阿明' }); </script>
使用方用解构拿到这份 user 再渲染。这是一个"组件已把数据算好,内容任你摆"的能力,用来做高度灵活的展示组件很顺手。
React 没有"插槽"的字眼,但 children 承担同一职责——组件 JSX 内部夹的内容会成为 children 传给组件:
function Panel({ title, children }) { return ( <section> <h2>{title}</h2> <div>{children}</div> </section> ); } // 用法 <Panel title="本周热销">给任意结构,收到 children</Panel>
当需要多个"具名位"时,React 常把 JSX 作为 props 传给多个槽(例如传 header 与 footer 两个 props),或用 slot 模式的 children。思想与 Vue 插槽完全相通。
插槽最常见的落地是"做一个可复用的页面壳",壳负责排版,壳内内容随页面变化。用 Vue 写一个带页头、左右栏、底部的布局组件:
<template> <div class="layout"> <header><slot name="side" /></header> <main><slot /></main> <footer><slot name="footer" /></footer> </div> </template>
使用方每次只需按位填充,排版与骨架由 Layout 统一负责:
<Layout> <template #side>侧边导航</template> 任意正文区域 <template #footer>版权信息</template> </Layout>
换个团队或换一套 UI 需求,也只需改写 Layout 一个文件,业务页面的 JSX 结构几乎不动。这种"骨架与填充分离"的收益,正是插槽相较纯 props 的核心价值:调用方拿到的是自由度,组件拿到的是结构与样式的复用。
| 诉求 | Vue | React |
|---|---|---|
| 默认可变内容 | 默认插槽 | children |
| 多个内容位 | 具名插槽 | 多个 JSX props |
| 把内部数据给内容 | 作用域插槽 | render prop |
场景判断:当组件的"某个部位永远可变且结构自由"时,就该考虑插槽/children;如果可变的是数据而非结构,props 更贴切。二者并不冲突,常常组合使用。

插槽还有一个常被忽略但很值钱的细节:给每个位写一个合理的默认内容。上面 Panel 的 <slot>默认内容</slot> 就是在"调用方没给东西"时兜底展示。别小看这一步,它在组件接口上约定了一件事——"这个位可以空着,空着长这样"。很多通用组件在初始版本就写好了默认,后续升级时不必因为某处没传而崩出空白,也更方便在默认里放骨架占位或提示文案。
同时约定"插槽到底该多薄"也不可省:一个组件若塞了五六个具名插槽,那它多半是把太多版面决策下放给了调用方,反而难维护。理想的外壳是"插槽位不多不少、默认值齐全、缺乏时也有兜底"。这两点——默认值与克制——让插槽用得既灵活又不会失控,是比"能用插槽"更高一层的"用好插槽"。把它们记进你的组件设计习惯,调用方和维持方都会感谢你。
组件能装内容、能通信了。接下来是样式这一容易被忽视的战场——如何让组件的样式互相不串色。下一节组件样式治理。