大家好,我是小杨,一个写了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>
五、插槽的常见使用场景
- 布局组件(比如卡片、弹窗、表格)
- 列表渲染(允许自定义每一项的UI)
- 高阶组件(比如封装一个可复用的逻辑,但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
最后感谢各位的耐心观看,既然都到这了,点个 👍赞再走吧!