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

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

相关推荐
一 乐5 小时前
婚纱摄影网站|基于ssm + vue婚纱摄影网站系统(源码+数据库+文档)
前端·javascript·数据库·vue.js·spring boot·后端
C_心欲无痕5 小时前
ts - tsconfig.json配置讲解
linux·前端·ubuntu·typescript·json
清沫5 小时前
Claude Skills:Agent 能力扩展的新范式
前端·ai编程
yinuo6 小时前
前端跨页面通信终极指南:方案拆解、对比分析
前端
北辰alk6 小时前
Vue 模板引擎深度解析:基于 HTML 的声明式渲染
vue.js
北辰alk6 小时前
Vue 自定义指令完全指南:定义与应用场景详解
vue.js
yinuo7 小时前
前端跨页面通讯终极指南⑨:IndexedDB 用法全解析
前端
北辰alk7 小时前
Vue 动态路由完全指南:定义与参数获取详解
vue.js
北辰alk7 小时前
Vue Router 完全指南:作用与组件详解
vue.js
北辰alk7 小时前
Vue 中使用 this 的完整指南与注意事项
vue.js