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

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

相关推荐
ZoeLandia16 分钟前
前端自动化测试:Jest、Puppeteer
前端·自动化测试·测试
alicema111118 分钟前
萤石摄像头C++SDK应用实例
开发语言·前端·c++·qt·opencv
阿维的博客日记20 分钟前
div和span区别
前端·javascript·html
长安城没有风24 分钟前
更适合后端宝宝的前端三件套之HTML
前端·html
伍哥的传说24 分钟前
Vue3 Anime.js超级炫酷的网页动画库详解
开发语言·前端·javascript·vue.js·vue·ecmascript·vue3
欢乐小v1 小时前
elementui-admin构建
前端·javascript·elementui
霸道流氓气质1 小时前
Vue中使用vue-3d-model实现加载3D模型预览展示
前端·javascript·vue.js
溜达溜达就好1 小时前
ubuntu22 npm install electron --save-dev 失败
前端·electron·npm
慧一居士1 小时前
Axios 完整功能介绍和完整示例演示
前端