Vue插槽全解析:3种插槽用法,让你的组件更灵活!💡

320 阅读3分钟

大家好,我是小杨,一个写了6年前端的老油条。今天咱们聊聊Vue里的插槽(Slot) ,这个功能看似简单,但用好了能让你的组件灵活度直接起飞!🛫

image.png

刚开始学Vue的时候,我也觉得插槽有点抽象,但后来发现它其实就是 "组件里的占位符" ,允许你在使用组件时往里塞自定义内容。下面我就用最直白的语言,带你搞懂3种插槽的用法!


1. 默认插槽:最简单的"占位坑"

默认插槽就是最基本的插槽,你在组件里挖个"坑",使用的时候往里填内容就行。

示例代码:

<!-- 子组件 MyButton.vue -->
<template>
  <button class="my-btn">
    <slot></slot>  <!-- 这里是插槽,等着被填充 -->
  </button>
</template>
<!-- 父组件使用 -->
<MyButton>
  点我!  <!-- 这里的内容会替换掉 <slot></slot> -->
</MyButton>

我的使用场景

  • 按钮、卡片等需要自定义内部内容的组件
  • 不想写死内容,让父组件决定显示什么

2. 具名插槽:多个插槽,各司其职

如果组件里有多个插槽位置,就需要具名插槽(给插槽起名字)。

示例代码:

<!-- 子组件 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>
<!-- 父组件使用 -->
<MyCard>
  <template v-slot:header>  
    <h2>我是标题</h2>  <!-- 插入到 name="header" 的插槽 -->
  </template>

  <p>我是内容...</p>  <!-- 默认插槽,不用写名字 -->

  <template #footer>  <!-- #footer 是 v-slot:footer 的缩写 -->
    <button>确定</button>
  </template>
</MyCard>

我的使用场景

  • 布局型组件(比如卡片、弹窗、表格)
  • 需要区分头部、内容、底部等不同区域的情况

3. 作用域插槽:子组件传数据给插槽

有时候,插槽内容需要访问子组件内部的数据,这时候就要用作用域插槽

示例代码:

<!-- 子组件 UserList.vue -->
<template>
  <ul>
    <li v-for="user in users" :key="user.id">
      <slot :user="user"></slot>  <!-- 把 user 数据传出去 -->
    </li>
  </ul>
</template>
<!-- 父组件使用 -->
<UserList>
  <template v-slot:default="slotProps">  <!-- 接收数据 -->
    <span>{{ slotProps.user.name }}</span> -
    <span>{{ slotProps.user.age }}岁</span>
  </template>
</UserList>

我的使用场景

  • 列表组件(比如表格、下拉菜单)
  • 需要自定义每一项的渲染方式

插槽的作用总结

  1. 提高组件复用性:同一个组件可以展示不同的内容
  2. 增强灵活性:父组件可以控制子组件的部分UI
  3. 解耦组件:让组件更专注于功能,而不是写死样式

我的实战经验

有一次我写一个<DataTable>组件,用作用域插槽让使用者可以自定义每一列的渲染方式,结果这个组件被全团队复用,省了好多重复代码!🎉

小技巧

  • v-slot 可以缩写为 #,比如 #header
  • 作用域插槽可以用解构,比如 v-slot="{ user }"

最后

插槽是Vue组件化的精髓之一,用好了能让你的代码更优雅、更灵活。刚开始可能有点绕,但多写几次就懂了!

⭐  写在最后

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

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

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

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

✅ 解答我文章中一些疑问

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

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

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

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