插槽:Vue里的‘占位符’,让组件更灵活!

大家好,我是小杨,一个写了6年前端的老码农。今天咱们聊聊Vue里的一个超级实用的功能------插槽(slot)

一、插槽是啥?

简单来说,插槽就是组件里的"占位符" ,它允许我们在使用组件时,往里面"塞"自定义的内容。

举个现实中的例子:

  • 你买了一个手机壳(组件),壳上预留了一个洞(插槽),你可以自己决定往洞里塞什么------可能是耳机孔、摄像头,甚至是个小风扇。
  • Vue的插槽也是一样,它让组件变得更灵活,可以动态插入内容。

二、基本用法

1. 默认插槽

假设我写了一个MyButton组件,但希望按钮的文本可以自定义:

html 复制代码
<!-- MyButton.vue -->
<template>
  <button class="my-btn">
    <slot></slot>  <!-- 这里是插槽,用来放自定义内容 -->
  </button>
</template>

使用的时候:

html 复制代码
<MyButton>点我!</MyButton>
<MyButton>提交</MyButton>

渲染结果:

html 复制代码
<button class="my-btn">点我!</button>
<button class="my-btn">提交</button>

<slot></slot>就是默认插槽,它会自动替换成组件标签里的内容。

2. 后备内容(默认值)

如果使用组件时没传内容,插槽可以设置默认值:

html 复制代码
<!-- MyButton.vue -->
<template>
  <button class="my-btn">
    <slot>默认按钮</slot>  <!-- 如果不传内容,就显示"默认按钮" -->
  </button>
</template>

使用:

html 复制代码
<MyButton></MyButton>  <!-- 渲染:<button class="my-btn">默认按钮</button> -->
<MyButton>确定</MyButton>  <!-- 渲染:<button class="my-btn">确定</button> -->

三、具名插槽(多个插槽)

有时候,我们想在一个组件里定义多个插槽,比如一个卡片组件,有标题、内容、底部三部分:

html 复制代码
<!-- MyCard.vue -->
<template>
  <div class="card">
    <header>
      <slot name="header"></slot>  <!-- 具名插槽 -->
    </header>
    <div class="content">
      <slot></slot>  <!-- 默认插槽 -->
    </div>
    <footer>
      <slot name="footer"></slot>  <!-- 具名插槽 -->
    </footer>
  </div>
</template>

使用时,用v-slot指定插槽名:

html 复制代码
<MyCard>
  <template v-slot:header>
    <h2>我的卡片标题</h2>
  </template>
  
  <p>这里是卡片内容...</p>  <!-- 默认插槽,不用写v-slot -->
  
  <template v-slot:footer>
    <button>确定</button>
  </template>
</MyCard>

v-slot:header 表示这个内容要放到name="header"的插槽里。

简写:#代替v-slot

Vue允许用#缩写:

html 复制代码
<template #header>
  <h2>我的卡片标题</h2>
</template>

四、作用域插槽(让插槽访问子组件数据)

有时候,我们希望插槽内容能访问子组件内部的数据。比如,我写了一个List组件,但希望外部能自定义渲染方式:

html 复制代码
<!-- List.vue -->
<template>
  <ul>
    <li v-for="item in items" :key="item.id">
      <slot :item="item"></slot>  <!-- 把item传给插槽 -->
    </li>
  </ul>
</template>

<script>
export default {
  data() {
    return {
      items: [
        { id: 1, name: '苹果' },
        { id: 2, name: '香蕉' },
      ]
    }
  }
}
</script>

使用时,用v-slot接收数据:

html 复制代码
<List>
  <template v-slot:default="slotProps">  <!-- 接收作用域数据 -->
    <span>{{ slotProps.item.name }}</span>
  </template>
</List>

slotProps 可以随便命名,它包含了子组件传给插槽的数据。

解构写法(更简洁)

html 复制代码
<List>
  <template v-slot:default="{ item }">  <!-- 直接解构 -->
    <span>{{ item.name }}</span>
  </template>
</List>

五、插槽的常见使用场景

  1. 布局组件(比如卡片、弹窗、表格)
  2. 列表渲染(允许自定义每一项的UI)
  3. 高阶组件(比如封装一个可复用的逻辑,但UI由外部决定)

六、总结

插槽的核心作用:让组件更灵活,允许外部自定义内容

插槽类型 作用 示例
默认插槽 基本占位 <slot></slot>
具名插槽 多个插槽 <slot name="header"></slot>
作用域插槽 子传数据给插槽 <slot :item="item"></slot>

记住:

  • 默认插槽<slot></slot>
  • 具名插槽<slot name="xxx"> + v-slot:xxx
  • 作用域插槽<slot :data="data"> + v-slot="props"

我是小杨,6年前端老司机,喜欢分享实用的前端技巧。如果觉得有用,点个赞再走吧!下期见~ 🚀

⭐ 写在最后

请大家不吝赐教,在下方评论或者私信我,十分感谢🙏🙏🙏.

✅ 认为我某个部分的设计过于繁琐,有更加简单或者更高逼格的封装方式

✅ 认为我部分代码过于老旧,可以提供新的API或最新语法

✅ 对于文章中部分内容不理解

✅ 解答我文章中一些疑问

✅ 认为某些交互,功能需要优化,发现BUG

✅ 想要添加新功能,对于整体的设计,外观有更好的建议

✅ 一起探讨技术加qq交流群:906392632

最后感谢各位的耐心观看,既然都到这了,点个 👍赞再走吧!

相关推荐
A_nanda29 分钟前
根据AI提示排查vue前端项目
前端·javascript·vue.js
happymaker06261 小时前
web前端学习日记——DAY05(定位、浮动、视频音频播放)
前端·学习·音视频
~无忧花开~1 小时前
React状态管理完全指南
开发语言·前端·javascript·react.js·前端框架
LegendNoTitle1 小时前
计算机三级等级考试 网络技术 选择题考点详细梳理
服务器·前端·经验分享·笔记·php
@大迁世界2 小时前
1.什么是 ReactJS?
前端·javascript·react.js·前端框架·ecmascript
BJ-Giser2 小时前
Cesium 基于EZ-Tree的植被效果
前端·可视化·cesium
王码码20353 小时前
Flutter for OpenHarmony:Flutter 三方库 algoliasearch 毫秒级云端搜索体验(云原生搜索引擎)
android·前端·git·flutter·搜索引擎·云原生·harmonyos
发现一只大呆瓜3 小时前
深入浅出 AST:解密 Vite、Babel编译的底层“黑盒”
前端·面试·vite
天天鸭4 小时前
前端仔写了个 AI Agent,才发现大模型只干了 10% 的活
前端·python·ai编程
发现一只大呆瓜4 小时前
前端模块化:CommonJS、AMD、ES Module三大规范全解析
前端·面试·vite