Vue3 插槽完整实战(具名插槽 + 动态插槽)

Vue3 插槽完整实战(具名插槽 + 动态插槽),以下会给你可直接运行的完整代码 ,包含父组件 + 子组件,实现:

  1. 基础具名插槽
  2. 灵活的动态插槽(根据名称自动匹配渲染)
  3. 作用域插槽(子传数据给父)

1. 子组件:SlotChild.vue(插槽容器)

这个组件定义多个具名插槽 + 动态插槽出口,提供默认内容。

vue 复制代码
<template>
  <div class="child-box">
    <h3>子组件(插槽容器)</h3>

    <!-- 1. 固定具名插槽:头部 -->
    <div class="slot-header">
      <slot name="header">
        <!-- 插槽默认内容:父组件不传时显示 -->
        <p>默认头部</p>
      </slot>
    </div>

    <!-- 2. 核心:动态插槽(根据名称灵活渲染) -->
    <div class="slot-dynamic" v-for="name in dynamicSlotNames" :key="name">
      <slot :name="name">默认 {{ name }} 区域内容</slot>
    </div>

    <!-- 3. 作用域插槽:子组件把数据传给父组件 -->
    <div class="slot-scope">
      <slot name="scope" :user="userInfo" :msg="scopeMsg">
        默认作用域插槽
      </slot>
    </div>

    <!-- 4. 匿名插槽(默认插槽) -->
    <div class="slot-default">
      <slot>默认匿名插槽</slot>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'

// 动态插槽名称列表 → 父组件可以灵活匹配
const dynamicSlotNames = ref(['top', 'center', 'bottom'])

// 作用域插槽要传递的数据
const userInfo = ref({ name: 'Vue新手', age: 20 })
const scopeMsg = ref('这是子组件传给父的消息')
</script>

<style scoped>
.child-box {
  border: 2px solid #42b983;
  padding: 20px;
  margin: 20px 0;
  border-radius: 8px;
}
.slot-header, .slot-dynamic, .slot-scope, .slot-default {
  margin: 10px 0;
  padding: 10px;
  border: 1px dashed #666;
}
</style>

子组件核心说明

  • name="header"固定具名插槽
  • v-for + :name="name"动态插槽(父组件想传几个就匹配几个)
  • :user="userInfo"作用域插槽(子 → 父传数据)
  • 不带 name 的 <slot>匿名默认插槽

2. 父组件:SlotParent.vue(使用插槽)

父组件通过 v-slot:名称(简写 #名称)匹配子组件插槽,支持动态名称

vue 复制代码
<template>
  <div class="parent-box">
    <h2>父组件(使用插槽)</h2>

    <SlotChild>
      <!-- 1. 匹配固定具名插槽:header -->
      <template #header>
        <h4 style="color: #2f4050;">✅ 父组件传入:头部插槽内容</h4>
      </template>

      <!-- 2. 动态匹配插槽:对应子组件 dynamicSlotNames -->
      <template #top>
        <span style="color: #409eff;">动态 top 区域</span>
      </template>

      <template #center>
        <span style="color: #e6a23c;">动态 center 区域</span>
      </template>

      <template #bottom>
        <span style="color: #67c23a;">动态 bottom 区域</span>
      </template>

      <!-- 3. 作用域插槽:接收子组件传过来的数据 -->
      <template #scope="scopeData">
        <div>
          <p>接收子数据:{{ scopeData.user.name }},年龄:{{ scopeData.user.age }}</p>
          <p>子消息:{{ scopeData.msg }}</p>
        </div>
      </template>

      <!-- 4. 匿名默认插槽 -->
      <div>✅ 父组件传入:默认匿名插槽内容</div>
    </SlotChild>
  </div>
</template>

<script setup>
// 引入子组件
import SlotChild from './SlotChild.vue'
</script>

<style scoped>
.parent-box {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
}
</style>

3. 最灵活方案:动态插槽名(进阶)

如果你想要完全根据变量自动渲染插槽 ,用动态指令

vue 复制代码
<template>
  <SlotChild>
    <!-- 变量控制插槽名称,实现 100% 动态 -->
    <template #[dynamicSlotName]>
      动态名称插槽内容
    </template>
  </SlotChild>
</template>

<script setup>
import SlotChild from './SlotChild.vue'
import { ref } from 'vue'

// 插槽名可以从接口、配置、循环中动态获取
const dynamicSlotName = ref('center') 
</script>

#[dynamicSlotName] = 动态绑定插槽名称,配置化、极高灵活性


4. 核心知识点总结

  1. 具名插槽

    • 子:<slot name="xxx">
    • 父:<template #xxx>
  2. 动态插槽(最实用)

    • 子:循环生成 <slot :name="item">
    • 父:用对应名称匹配
    • 超级灵活:适合表单、弹窗、列表、卡片等可复用组件
  3. 作用域插槽

    • 子:<slot :数据名="值">
    • 父:<template #xxx="接收对象">
  4. 简写规则

    • v-slot:header 简写为 #header

总结

  • 你可以直接复制这两个文件运行
  • 子组件负责定义插槽出口
  • 父组件负责填充内容
  • 动态插槽让组件高度复用、可配置、可扩展
  • 作用域插槽解决子组件数据传给父插槽使用的场景
相关推荐
fei_sun1 小时前
Vue+SpingBoot+MyBaits框架
前端·javascript·vue.js
爱吃鱼的锅包肉1 小时前
利用css+js实现一个图片随鼠标滑动裁剪的功能
前端·javascript·css·计算机外设
儒雅的烤地瓜2 小时前
小程序 | Vue小程序开发框架:MPvue与UniApp深度解析
前端·vue.js·uni-app·nodejs·cli·mpvue
小鸡脚来咯2 小时前
正则表达式考点
java·开发语言·前端
ujainu2 小时前
Electron 主进程与渲染进程通信详解:HarmonyOS PC基于 `ipcRenderer.send` 与 `ipcMain.on` 的双向数据传输
javascript·electron·harmonyos
Cg136269159742 小时前
JS-对象-
开发语言·javascript·ecmascript
IT_陈寒2 小时前
SpringBoot开发效率提升50%的5个隐藏技巧,官方文档都没告诉你!
前端·人工智能·后端
鹏北海2 小时前
TypeScript 装饰器完全指南
前端·typescript
zhaoyin19942 小时前
Vue面试题笔记
javascript·vue.js·笔记