Vue.js插槽是组件内容分发机制,含默认插槽(无name)、具名插槽(用name区分区域)、作用域插槽(传递子组件数据供父组件定制渲染)、动态与条件插槽(运行时控制插槽名或显示)。

Vue.js 中的 Slots(插槽) 是实现组件内容分发的核心机制,它让父组件能向子组件“注入”任意模板结构,从而提升组件的复用性与灵活性。理解插槽不是为了记住语法,而是掌握“谁控制内容、谁决定渲染位置”这一关键逻辑。
默认插槽:最基础的内容传递方式
当子组件模板中只写一个 <slot></slot>,且没有 name 属性时,就启用了默认插槽。父组件中写在组件标签内的所有内容,都会被自动插入到这个位置。
例如:
子组件 Card.vue:
立即学习“前端免费学习笔记(深入)”;
<template><div class="card">
<h3>{{ title }}</h3>
<slot></slot> <!-- 内容将插入这里 -->
</div>
</template>
父组件中使用:
<Card title="用户信息"><p>姓名:张三</p>
<p>邮箱:zhangsan@example.com</p>
</Card>
渲染结果就是标题加两段用户信息——内容由父组件提供,位置由子组件的 <slot> 决定。
具名插槽:按区域精准投递内容
当子组件有多个可替换区域(如头部、主体、底部),就需要用 name 区分插槽。父组件通过 v-slot:name(简写为 #name)指定内容去向。
子组件中定义:
Vue 3 组合式 API 与 最佳实践,涵盖代码组织、useXxx 模式、组合式函数设计、Store 集成、响应式优化及功能抽取。
<main><slot name="default">默认正文</slot></main>
<footer><slot name="footer">默认页脚</slot></footer>
父组件中对应填充:
<Card><template #header><h2>欢迎卡片</h2></template>
<template #default><p>这是主要内容区</p></template>
<template #footer><button>确认</button></template>
</Card>
注意:#default 可省略为默认插槽写法(即直接写在标签内),但显式命名更清晰,尤其在混合使用时。
作用域插槽:把子组件数据“传出来”供父组件定制渲染
插槽不仅能接收内容,还能接收子组件内部的数据。子组件在 <slot> 上用 v-bind 绑定属性,父组件通过 v-slot:xxx="scope" 解构获取。
子组件 List.vue 渲染列表项,并把每一项数据传出:
<li v-for="item in items" :key="item.id">
<slot :item="item" :index="loop.index"></slot>
</li>
</ul>
父组件自定义每项显示方式:
<List :items="users"><template #default="{ item, index }">
<span>【{{ index + 1 }}】{{ item.name }} ({{ item.role }})</span>
</template>
</List>
这样,渲染逻辑和数据逻辑分离:子组件管循环与数据流,父组件管界面长什么样。
动态插槽名与条件插槽:增强运行时控制力
插槽名支持动态绑定,配合 v-if 或计算属性,可实现“根据状态切换插槽内容”。比如表单组件根据字段类型切换输入控件:
- 子组件中:
<slot :name="field.type"></slot> - 父组件中:
<template #[field.type]="scope">...</template>,或用v-if控制不同#text/#number插槽的显示
这种写法适合构建低代码表单、可配置布局等场景,让插槽真正成为“内容策略”的执行点。

















