插槽: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

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

相关推荐
用户841794814567 小时前
vxe-gantt table 甘特图如何设置任务视图每一行的背景色
vue.js
前端老宋Running7 小时前
一次从“卡顿地狱”到“丝般顺滑”的 React 搜索优化实战
前端·react.js·掘金日报
隔壁的大叔7 小时前
如何自己构建一个Markdown增量渲染器
前端·javascript
用户4445543654267 小时前
Android的自定义View
前端
WILLF7 小时前
HTML iframe 标签
前端·javascript
枫,为落叶7 小时前
Axios使用教程(一)
前端
小章鱼学前端7 小时前
2025 年最新 Fabric.js 实战:一个完整可上线的图片选区标注组件(含全部源码).
前端·vue.js
ohyeah8 小时前
JavaScript 词法作用域、作用域链与闭包:从代码看机制
前端·javascript
流星稍逝8 小时前
手搓一个简简单单进度条
前端
uup8 小时前
JavaScript 中 this 指向问题
javascript