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

总结

  • 你可以直接复制这两个文件运行
  • 子组件负责定义插槽出口
  • 父组件负责填充内容
  • 动态插槽让组件高度复用、可配置、可扩展
  • 作用域插槽解决子组件数据传给父插槽使用的场景
相关推荐
无心使然云中漫步2 分钟前
Openlayers调用ArcGis地图服务之一 —— 地图切片(/tile)
前端·arcgis·vue·数据可视化
火山口车神丶7 分钟前
如何借助AI进行模块封装DIY
javascript·人工智能·算法
angushine26 分钟前
Python常用方法
开发语言·前端·python
C澒29 分钟前
AI 生码 - D2C:Figma to Code 全流程实现
前端·低代码·ai编程·figma
敲代码的鱼哇30 分钟前
发送短信/拨打电话/获取联系人能力 UTS 插件(cz-sms)
android·前端·ios·uni-app·安卓·harmonyos·鸿蒙
搬搬砖得了33 分钟前
Vue 响应式对象异步赋值作为 Props:二次渲染问题与组件设计哲学
前端·vue.js
张西餐1 小时前
Promise的理解
前端
悟空瞎说1 小时前
收藏即复用!50个极致实用JavaScript单行代码,前端开发效率直接拉满
javascript
天渺工作室1 小时前
别再写改名脚本了,一个 Vite 插件搞定压缩、校验、自动哈希命名vite-plugin-pack-orchestrator
前端·vite
薯老板1 小时前
事件循环(Event Loop)
javascript