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. 支持动态样式

相关推荐
掘金安东尼1 小时前
⏰前端周刊第 456 期(v2026.3.15)
前端·javascript·面试
nibabaoo2 小时前
前端开发攻略---在 Vue 3 项目中使用 vue-i18n 实现国际化多语言
前端·javascript·国际化·i18n·vue3
qq_437100662 小时前
ElasticSearch相关记录
大数据·前端·javascript·elasticsearch·全文检索
CHU7290352 小时前
剧本杀组车约玩小程序前端功能版块设计及玩法介绍
前端·小程序
清空mega2 小时前
《Vue3 模板进阶:class/style 绑定、事件对象、修饰符、表单处理与高频易错点》
前端·javascript·vue.js
还是大剑师兰特2 小时前
Vue3 插槽完整实战(具名插槽 + 动态插槽)
前端·javascript·vue.js
fei_sun2 小时前
Vue+SpingBoot+MyBaits框架
前端·javascript·vue.js
爱吃鱼的锅包肉2 小时前
利用css+js实现一个图片随鼠标滑动裁剪的功能
前端·javascript·css·计算机外设
儒雅的烤地瓜2 小时前
小程序 | Vue小程序开发框架:MPvue与UniApp深度解析
前端·vue.js·uni-app·nodejs·cli·mpvue