文章目录
- 1. 核心:通用动态插槽组件
-
- `components/DynamicSlotBox.vue`
- 2. 使用页面 1:表单卡片(最常用场景)
-
- `views/FormPage.vue`
- 3. 使用页面 2:列表卡片(完全不同场景)
-
- `views/ListPage.vue`
- ✏️ 核心用法总结
-
- 子组件(通用)
- 父组件(使用)
- 🎯 这个组件的超级优势

这里封装一个开箱即用、任意页面都能复用的 DynamicSlotBox 通用插槽组件。
特点:
- 支持任意插槽名称(配置驱动)
- 支持默认内容
- 支持作用域传参(子→父传数据)
- 支持循环批量渲染插槽
- 任意页面引入就能用,无需改组件内部代码
直接给你完整 3 个文件:
1. 核心:通用动态插槽组件
components/DynamicSlotBox.vue
<template>
<div class="dynamic-slot-box" :style="wrapperStyle">
<!– 批量循环渲染插槽:根据传入的 slotNames 生成 –>
<div
class="slot-item"
v-for="slotName in slotNames"
:key="slotName"
:style="itemStyle"
>
<!– 核心:动态具名插槽 + 作用域数据 –>
<slot :name="slotName" :slotData="scopeData">
<!– 默认内容 –>
<div class="slot-default-tip">
插槽「{{ slotName }}」未填充内容
</div>
</slot>
</div>
</div>
</template>
<script setup>
import { computed } from 'vue'
// 父组件传入配置:插槽名称数组
const props = defineProps({
// 插槽名称列表,例如 ['header', 'body', 'footer', 'table']
slotNames: {
type: Array,
required: true,
default: () => []
},
// 可选:传给所有插槽的公共作用域数据
scopeData: {
type: Object,
default: () => ({})
},
// 外层样式
wrapperStyle: {
type: Object,
default: () => ({})
},
// 每个插槽项样式
itemStyle: {
type: Object,
default: () => ({})
}
})
</script>
<style scoped>
.dynamic-slot-box {
margin: 16px 0;
border: 1px solid #eee;
border-radius: 8px;
padding: 12px;
}
.slot-item {
margin: 8px 0;
padding: 12px;
min-height: 40px;
border: 1px dashed #ccc;
border-radius: 6px;
}
.slot-default-tip {
color: #999;
font-size: 13px;
}
</style>
2. 使用页面 1:表单卡片(最常用场景)
views/FormPage.vue
<template>
<div>
<h2>表单页面(使用通用插槽组件)</h2>
<!– 只需传入插槽名称数组,即可自动生成插槽 –>
<DynamicSlotBox
:slotNames="['formHeader', 'formBody', 'formFooter']"
:scopeData="{ formId: 10086, user: '张三' }"
>
<!– 填充头部插槽 –>
<template #formHeader>
<h3>用户编辑表单</h3>
</template>
<!– 填充表单体插槽 –>
<template #formBody>
<div>姓名:<input /></div>
<div>年龄:<input /></div>
</template>
<!– 接收子组件传来的作用域数据 –>
<template #formFooter="scope">
<button>提交</button>
<p>表单ID:{{ scope.slotData.formId }}</p>
</template>
</DynamicSlotBox>
</div>
</template>
<script setup>
import DynamicSlotBox from '@/components/DynamicSlotBox.vue'
</script>
3. 使用页面 2:列表卡片(完全不同场景)
views/ListPage.vue
<template>
<div>
<h2>列表页面(复用同一个插槽组件)</h2>
<DynamicSlotBox
:slotNames="['listTop', 'listTable', 'listPagination']"
:scopeData="{ total: 100 }"
>
<template #listTop>
<button>新增</button>
<button>批量删除</button>
</template>
<template #listTable>
<table border="1" cellpadding="10">
<tr><td>列表内容 1</td></tr>
<tr><td>列表内容 2</td></tr>
</table>
</template>
<template #listPagination="scope">
共 {{ scope.slotData.total }} 条
</template>
</DynamicSlotBox>
</div>
</template>
<script setup>
import DynamicSlotBox from '@/components/DynamicSlotBox.vue'
</script>
✏️ 核心用法总结
子组件(通用)
<slot :name="slotName" :slotData="scopeData" />
父组件(使用)
<DynamicSlotBox :slotNames="['A','B','C']">
<template #A> 内容A </template>
<template #B> 内容B </template>
<template #C> 内容C </template>
</DynamicSlotBox>

