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

相关推荐
落魄江湖行2 分钟前
入门篇二:Nuxt 4路由自动生成:告别手动配置路由的日子
前端·vue.js·typescript·nuxt4
CQU_JIAKE1 小时前
4.4【Q】
java·前端·javascript
小陈工1 小时前
Python Web开发入门(十二):使用Flask-RESTful构建API——让后端开发更优雅
开发语言·前端·python·安全·oracle·flask·restful
木斯佳1 小时前
前端八股文面经大全:字节前端一面(2026-04-03)·面经深度解析
前端·面试题·面经
xiaotao1311 小时前
第八章:实战项目案例
前端·vue.js·vite·前端打包
GISer_Jing1 小时前
Electron 全场景调试实战指南
javascript·electron·状态模式
We་ct1 小时前
JS手撕:性能优化、渲染技巧与定时器实现
开发语言·前端·javascript·面试·性能优化·定时器·性能
taWSw5OjU1 小时前
vue对接海康摄像头-H5player
开发语言·前端·javascript
huwuhang2 小时前
跨平台电子书阅读器 | Readest最新版 安卓版+PC版全平台
android·前端·javascript
C澒2 小时前
AI 生码:RAG 检索优化实现可评估、可回溯工程化
前端·ai编程