Vue 3 插槽(Slot)详解

🧩 一、什么是插槽(Slot)

插槽(Slot) 是 Vue 中的一个非常强大的特性,用于在 组件之间传递结构化内容。

简而言之:

插槽就是 "占位符",父组件可以在这个占位符中插入任意模板内容。


🧱 二、插槽的三种类型

Vue 3 中主要有三类插槽:

  1. 默认插槽(Default Slot)

  2. 具名插槽(Named Slot)

  3. 作用域插槽(Scoped Slot)


🧭 三、默认插槽(Default Slot)

🔹 子组件定义插槽

html 复制代码
<!-- Child.vue -->
<template>
  <div class="child">
    <h3>我是子组件</h3>
    <slot></slot> <!-- 插槽占位 -->
  </div>
</template>

🔹 父组件传入内容

html 复制代码
<!-- Parent.vue -->
<template>
  <Child>
    <p>这是插入到默认插槽的内容。</p>
  </Child>
</template>

🔹 渲染结果

html 复制代码
<div class="child">
  <h3>我是子组件</h3>
  <p>这是插入到默认插槽的内容。</p>
</div>

如果父组件没有传入任何内容,Vue 会使用 默认内容:

html 复制代码
<slot>这里是默认内容</slot>

🏷️ 四、具名插槽(Named Slot)

当一个组件有多个插槽时,就需要用名字来区分。

🔹 子组件定义

html 复制代码
<!-- Child.vue -->
<template>
  <header>
    <slot name="header">默认头部</slot>
  </header>
  <main>
    <slot>默认主体</slot>
  </main>
  <footer>
    <slot name="footer">默认底部</slot>
  </footer>
</template>

🔹 父组件传入

html 复制代码
<template>
  <LayoutComponent>
    <!-- Vue 3 语法:使用 v-slot 指令 -->
    <template v-slot:header>
      <h1>网站标题</h1>
      <nav>导航菜单</nav>
    </template>
    
    <template v-slot:content>
      <article>
        <h2>文章标题</h2>
        <p>文章内容...</p>
      </article>
    </template>
    
    <template v-slot:sidebar>
      <div class="sidebar">
        <h3>侧边栏</h3>
        <ul>
          <li>链接1</li>
          <li>链接2</li>
        </ul>
      </div>
    </template>
    
    <template v-slot:footer>
      <p>版权信息 © 2023</p>
    </template>
  </LayoutComponent>
</template>

💡 注意:

  • #header 是 v-slot:header 的语法糖。

  • 默认插槽用 #default 或直接写内容。


🧮 五、作用域插槽(Scoped Slot)

作用域插槽允许子组件 向父组件传递数据。

🔹 子组件提供数据

html 复制代码
<!-- Child.vue -->
<template>
  <ul>
    <slot :items="list"></slot>
  </ul>
</template>

<script setup>
const list = ['苹果', '香蕉', '橘子']
</script>

🔹 父组件使用插槽并接收数据

html 复制代码
<!-- Parent.vue -->
<template>
  <Child v-slot="{ items }">
    <li v-for="(item, i) in items" :key="i">{{ i + 1 }} - {{ item }}</li>
  </Child>
</template>

渲染结果:

html 复制代码
<ul>
  <li>1 - 苹果</li>
  <li>2 - 香蕉</li>
  <li>3 - 橘子</li>
</ul>

💡 说明

  • 子组件通过 slot 标签上的属性向父组件 暴露数据;

  • 父组件使用 v-slot="{ ... }" 解构这些数据;

  • 这就是"作用域插槽":父组件可以访问子组件提供的"插槽上下文"。


🧱 六、v-slot 完整语法总结

语法形式 用法说明
<template v-slot:header> 具名插槽
<template #header> 具名插槽(语法糖)
<template v-slot:default> 默认插槽
<template #default> 默认插槽(语法糖)
<Child v-slot="{ data }"> 作用域插槽
<Child #default="{ data }"> 作用域插槽语法糖

🧠 七、插槽底层原理(简述)

Vue 的插槽在编译阶段会被转换成渲染函数(render function)的一部分:

  • 子组件模板中的 <slot> 会生成一个 slot 函数调用;

  • 父组件传入的 <template v-slot> 会被编译为一个 函数;

  • 渲染时,Vue 会把父组件提供的函数传递给子组件,子组件在执行时调用它,形成一种 内容分发机制。

所以插槽本质上是:

"通过函数传递模板内容" 的机制。


⚙️ 八、综合示例

html 复制代码
<!-- Card.vue -->
<template>
  <div class="card">
    <header><slot name="header">默认标题</slot></header>
    <main><slot :info="info"></slot></main>
    <footer><slot name="footer">默认页脚</slot></footer>
  </div>
</template>

<script setup>
const info = { author: 'smatter er', date: '2025-10-30' }
</script>
html 复制代码
<!-- App.vue -->
<template>
  <Card>
    <template #header>
      <h2>文章标题</h2>
    </template>

    <template #default="{ info }">
      <p>作者:{{ info.author }},日期:{{ info.date }}</p>
    </template>

    <template #footer>
      <button>阅读全文</button>
    </template>
  </Card>
</template>

渲染结果:

html 复制代码
<div class="card">
  <header><h2>文章标题</h2></header>
  <main><p>作者:smatter er,日期:2025-10-30</p></main>
  <footer><button>阅读全文</button></footer>
</div>

🧩 九、插槽的使用建议

✅ 适用场景:

  • 通用组件(如卡片、弹窗、表格);

  • 灵活布局(header、footer、sidebar);

  • 组件内动态内容插入。

⚠️ 注意事项:

  • 插槽内容在父组件作用域中编译;

  • 子组件只能通过作用域插槽提供数据;

  • 避免滥用插槽导致组件复杂化。

相关推荐
Dream-Y.ocean4 小时前
鸿蒙PC平台宅匠 3D 室内设计适配实战:基于 Electron 壳方案的 Three.js 双渲染引擎与参数化户型编辑器开发
javascript·3d·harmonyos
Csvn5 小时前
性能监控
前端
Highcharts.js5 小时前
Highcharts Gantt使用符号的自定义数据标签开发甘特图示例
javascript·甘特图·highcharts·图表开发·实战代码·响应式图表
Csvn6 小时前
构建工具
前端
FRing036 小时前
vue2干货总结3(computed计算属性、watch监听器)
开发语言·前端·vue.js·vue2
Java小卷7 小时前
JuanForm vs FormCreate!Vue3 表单引擎联动配置 PK!
vue.js·低代码
kyriewen8 小时前
Skills 榜前 10 我全装了:只有 3 个能直接用
前端·javascript·程序员
IT_陈寒9 小时前
当Java的hashCode遇上Lombok,我的缓存被全清了
前端·人工智能·后端
工控丫丫9 小时前
帆软看板中经常使用的公式函数及经常搭的组合
前端·javascript·数据库
jerrywus9 小时前
我用 GPT-6.1-sol 做了台会讲解的 3D 售货机:60 罐饮料,一口没喝上
前端·agent·claude