Vue3 通用可复用动态插槽组件(终极版)

文章目录

这里封装一个开箱即用、任意页面都能复用DynamicSlotBox 通用插槽组件

特点:

  • 支持任意插槽名称(配置驱动)
  • 支持默认内容
  • 支持作用域传参(子→父传数据)
  • 支持循环批量渲染插槽
  • 任意页面引入就能用,无需改组件内部代码

直接给你完整 3 个文件

  1. 通用插槽组件(只写一次,到处复用)
  2. 使用页面示例 1
  3. 使用页面示例 2

1. 核心:通用动态插槽组件

components/DynamicSlotBox.vue

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

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

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>

✏️ 核心用法总结

子组件(通用)

vue 复制代码
<slot :name="slotName" :slotData="scopeData" />

父组件(使用)

vue 复制代码
<DynamicSlotBox :slotNames="['A','B','C']">
  <template #A> 内容A </template>
  <template #B> 内容B </template>
  <template #C> 内容C </template>
</DynamicSlotBox>

🎯 这个组件的超级优势

  1. 一次封装,全局复用
  2. 不修改组件代码,只需配置数组
  3. 支持任意业务:表单、列表、弹窗、步骤、卡片
  4. 支持作用域插槽,子传父数据
  5. 自带默认内容,不填插槽也不报错
  6. 支持动态样式

相关推荐
QQ1__8115175151 小时前
Spring boot名城小区物业管理系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】
前端·vue.js·spring boot
钛态1 小时前
前端微前端架构:大项目的救命稻草还是自找麻烦?
前端·vue·react·web
一粒黑子1 小时前
【实战解析】阿里开源 PageAgent:纯前端 GUI Agent,一行JS让网页支持自然语言操控
前端·javascript·开源
独角鲸网络安全实验室1 小时前
2026微信小程序抓包全解析:从实操落地到合规风控,解锁前端调试新范式
前端·微信小程序·小程序·抓包·系统代理绕过·https证书严格校验·进程隔离
紫微AI1 小时前
前端文本测量成了卡死一切创新的最后瓶颈,pretext实现突破了
前端·人工智能·typescript
GISer_Jing1 小时前
AI前端(From豆包)
前端·aigc·ai编程
IT枫斗者1 小时前
前端部署后如何判断“页面是不是最新”?一套可落地的版本检测方案(适配 Vite/Vue/React/任意 SPA)
前端·javascript·vue.js·react.js·架构·bug
测试修炼手册1 小时前
[测试技术] 深入理解 JSON Web Token (JWT)
前端·json
AI老李1 小时前
2026 年 Web 前端开发的 8 个趋势!
前端
里欧跑得慢1 小时前
15. Web可访问性最佳实践:让每个用户都能平等访问
前端·css·flutter·web