Vue 插槽 (slot) 完全指南
1. 什么是 slot
slot 插槽,可以理解为 slot 在组件模板中占好了位置,当使用该组件标签时,组件标签里面的内容就会自动填坑(替换组件模板中 slot 位置),作为承载分发内容的出口。
2. 使用场景
通过插槽可以让用户拓展组件,从而更好地复用组件和对其做定制化处理。
如果父组件在使用到一个复用组件时,获取这个组件在不同地方有少量更改,重写组件是不明智的。通过 slot 插槽向组件内部指定位置传递内容,可以完成这个复用组件在不同场景的应用。
常见的应用场景:布局组件、表格列、下拉选、弹框显示内容等。
3. 插槽的分类
默认插槽
子组件用 <slot> 标签确定渲染位置,标签里面可以放 DOM 结构。当父组件使用没有往插槽传入内容时,标签内的 DOM 结构会显示在页面。
具名插槽
子组件用 name 属性表示插槽的名字,不传则为默认插槽。父组件中在使用时在默认插槽的基础上加上 v-slot 属性或 #,值为子组件插槽 name 属性值。
子组件 Child.vue:
<template>
<slot>插槽后备的内容</slot>
<slot name="content">插槽后备的内容</slot>
</template>
父组件:
<child>
<template v-slot:default>具名插槽</template>
<!-- 具名插槽用插槽名做参数 -->
<template v-slot:content>内容...</template>
</child>
作用域插槽
子组件在作用域上绑定属性来将子组件的信息传给父组件使用,这些属性会被挂在父组件 v-slot 接收的对象上。父组件中在使用时通过 v-slot:(简写:#)获取子组件的信息,在内容中使用。
子组件:
<template>
<slot name="footer" :testProps="子组件的值">
<h3>没传 footer 插槽</h3>
</slot>
</template>
父组件:
<child>
<!-- 把 v-slot 的值指定为作用域上下文对象 -->
<template v-slot:default="slotProps">
来自子组件数据:{{ slotProps.testProps }}
</template>
<template #default="slotProps">
来自子组件数据:{{ slotProps.testProps }}
</template>
</child>
4. 原理
slot 本质上是返回 VNode 的函数。一般情况下,Vue 中的组件要渲染到页面上需要经过 template -> render function -> VNode -> DOM 过程。插槽同样遵循这一过程:在父组件中解析插槽,生成对应的 VNode;在子组件渲染时把插槽对应的 VNode 渲染到指定位置。
来源整理自:vue3js.cn 面试官系列



