大家好,我是小杨,一个写了6年前端的老油条。今天咱们聊聊Vue里的插槽(Slot) ,这个功能看似简单,但用好了能让你的组件灵活度直接起飞!🛫
刚开始学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>
我的使用场景:
- 列表组件(比如表格、下拉菜单)
- 需要自定义每一项的渲染方式
插槽的作用总结
- 提高组件复用性:同一个组件可以展示不同的内容
- 增强灵活性:父组件可以控制子组件的部分UI
- 解耦组件:让组件更专注于功能,而不是写死样式
我的实战经验
有一次我写一个<DataTable>组件,用作用域插槽让使用者可以自定义每一列的渲染方式,结果这个组件被全团队复用,省了好多重复代码!🎉
小技巧:
v-slot可以缩写为#,比如#header- 作用域插槽可以用解构,比如
v-slot="{ user }"
最后
插槽是Vue组件化的精髓之一,用好了能让你的代码更优雅、更灵活。刚开始可能有点绕,但多写几次就懂了!
⭐ 写在最后
请大家不吝赐教,在下方评论或者私信我,十分感谢🙏🙏🙏.
✅ 认为我某个部分的设计过于繁琐,有更加简单或者更高逼格的封装方式
✅ 认为我部分代码过于老旧,可以提供新的API或最新语法
✅ 对于文章中部分内容不理解
✅ 解答我文章中一些疑问
✅ 认为某些交互,功能需要优化,发现BUG
✅ 想要添加新功能,对于整体的设计,外观有更好的建议
✅ 一起探讨技术加qq交流群:906392632
最后感谢各位的耐心观看,既然都到这了,点个 👍赞再走吧!