Vue slot 插槽的使用
Vue 插槽的三种类型及其使用场景
问题
Vue 中的 slot 是什么?有哪些使用场景?
解答
slot 是什么
slot 插槽是组件模板中的占位符,用于承载分发内容。当使用组件时,组件标签内的内容会自动填充到 slot 位置。
可以类比为插卡式游戏机:组件暴露插槽,用户插入自定义内容。
使用场景
插槽让组件更灵活,可以在不同场景下复用组件并做定制化处理。常见场景包括:
- 布局组件
- 表格列定制
- 下拉选项
- 弹框内容
默认插槽
子组件用 <slot> 标签确定渲染位置,标签内可放默认内容。
子组件 Child.vue:
<template>
<slot>
<p>插槽后备的内容</p>
</slot>
</template>
父组件:
<Child>
<div>默认插槽</div>
</Child>
具名插槽
子组件用 name 属性标识插槽,父组件用 v-slot 指定插槽名。
子组件 Child.vue:
<template>
<slot>插槽后备的内容</slot>
<slot name="content">插槽后备的内容</slot>
</template>
父组件:
<child>
<template v-slot:default>具名插槽</template>
<template v-slot:content>内容...</template>
</child>
作用域插槽
子组件通过绑定属性将数据传给父组件,父组件通过 v-slot 接收。
子组件 Child.vue:
<template>
<slot name="footer" testProps="子组件的值">
<h3>没传footer插槽</h3>
</slot>
</template>
父组件:
<child>
<template v-slot:default="slotProps">
来自子组件数据:{{slotProps.testProps}}
</template>
<!-- 简写 -->
<template #default="slotProps">
来自子组件数据:{{slotProps.testProps}}
</template>
</child>
语法说明
v-slot只能用在<template>上,但只有默认插槽时可以直接用在组件标签上- 默认插槽名为
default,可省略 - 缩写为
#时不能省略参数,需写成#default - 支持解构:
v-slot="{user}",重命名:v-slot="{user: newName}",默认值:v-slot="{user = '默认值'}"
实现原理
slot 本质是返回 VNode 的函数。组件渲染过程:template → render function → VNode → DOM。
定义组件:
Vue.component('button-counter', {
template: '<div><slot>我是默认内容</slot></div>'
})
使用组件:
new Vue({
el: '#app',
template: '<button-counter><span>我是slot传入内容</span></button-counter>',
components: {buttonCounter}
})
生成的渲染函数:
(function anonymous() {
with(this){
return _c('div',[_t("default",[_v("我是默认内容")])],2)
}
})
其中 _t 是 renderSlot 函数,用于渲染插槽。renderSlot 接收插槽名、默认内容、props 等参数,通过 this.$scopedSlots 获取父组件传入的内容。
作用域插槽能传递数据是因为 renderSlot 执行时会传入 props,父组件通过 v-slot 接收这些数据。
关键点
- slot 是组件内容分发机制,分为默认插槽、具名插槽和作用域插槽三种
- 默认插槽直接在组件标签内写内容,具名插槽用
v-slot:name指定,作用域插槽可接收子组件数据 v-slot可简写为#,支持解构和默认值语法- slot 本质是返回 VNode 的函数,通过
$slots和$scopedSlots实现内容传递
目录