提示:插槽的目的是让我买原来的设备具备更多的扩展性。
文章目录
- 前言
- 在组件中定义插槽(子组件视角)
- 1. 默认插槽
- 2. 具名插槽(带名称的插槽)
- 3. 作用域插槽(带数据的插槽)
- 使用插槽(父组件视角)
- 1. 使用默认插槽
- 2. 使用具名插槽(案例解析)
- 3. 使用作用域插槽
- JeecgBoot 案例深度解析
- 原代码片段:
- 实现机制:
- 完整示例:带作用域的表格组件
- 子组件定义:
- 父组件使用:
- 插槽与 Props 的对比
- 最佳实践建议
前言
提示:这里可以添加本文要记录的大概内容:
插槽用于组件内容分发,实现父组件向子组件传递模板内容
插槽(Slot) 是 Vue 组件化开发中用于内容分发的机制,它允许父组件向子组件传递模板片段,实现组件内容的动态组合。通过插槽可以实现:
- 内容定制:父组件可自定义子组件的部分内容
- 结构复用:保持组件核心逻辑的同时提供布局灵活性
- 作用域控制:子组件可向插槽传递数据(作用域插槽)
在组件中定义插槽(子组件视角)
1. 默认插槽
<!-- 子组件 ChildComponent.vue -->
<template>
<div class="container">
<!-- 默认插槽位置 -->
<slot>
<!-- 默认内容(可选) -->
<p>当父组件不提供内容时显示这个默认文本</p>
</slot>
</div>
</template>
2. 具名插槽(带名称的插槽)
<!-- 子组件 JSelectBizComponent.vue -->
<template>
<a-col class="left">
<!-- 具名插槽 -->
<slot name="left">
<!-- 默认内容 -->
<a-select .../>
</slot>
</a-col>
</template>
3. 作用域插槽(带数据的插槽)
<!-- 子组件 ScopedComponent.vue -->
<template>
<div>
<slot name="item"
:itemData="internalData"
:index="currentIndex">
</slot>
</div>
</template>
使用插槽(父组件视角)
1. 使用默认插槽
<!-- 父组件 ParentComponent.vue -->
<child-component>
<!-- 插入默认插槽的内容 -->
<h2>自定义标题</h2>
<p>自定义内容</p>
</child-component>
2. 使用具名插槽(案例解析)
<!-- 父组件使用 JSelectBizComponent -->
<j-select-biz-component>
<!-- #left 对应子组件的 name="left" 插槽 -->
<template #left>
<!-- 覆盖默认的 a-select -->
<a-input placeholder="自定义输入框" />
<a-button type="primary">搜索</a-button>
</template>
</j-select-biz-component>
3. 使用作用域插槽
<!-- 父组件使用 ScopedComponent -->
<scoped-component>
<template #item="slotProps">
<!-- 使用子组件传递的数据 -->
<p>索引:{{ slotProps.index }}</p>
<p>数据:{{ slotProps.itemData }}</p>
</template>
</scoped-component>
JeecgBoot 案例深度解析
原代码片段:
<!-- JSelectBizComponent 组件 -->
<template>
<a-col class="left">
<slot name="left">
<a-select ...></a-select>
</slot>
</a-col>
</template>
实现机制:
- 插槽定义:通过
<slot name="left">
定义具名插槽 - 默认内容:当父组件不提供插槽内容时,显示
<a-select>
组件 - 插槽覆盖:父组件可以通过
#left
完全替换默认内容 - 样式控制:通过 CSS 类
.left
控制布局样式
完整示例:带作用域的表格组件
子组件定义:
<!-- SmartTable.vue -->
<template>
<a-table :dataSource="data">
<template v-for="col in columns" :slot="col.slotName">
<slot :name="col.slotName"
:column="col"
:record="col.record"
:text="col.text">
</slot>
</template>
</a-table>
</template>
父组件使用:
<smart-table :columns="columns">
<template #action="scope">
<a-button @click="handleEdit(scope.record)">编辑</a-button>
<a-button @click="handleDelete(scope.record.id)">删除</a-button>
</template>
<template #status="scope">
<a-tag :color="scope.text | statusColor">
{{ scope.text | statusText }}
</a-tag>
</template>
</smart-table>
插槽与 Props 的对比
特性 | 插槽(Slot) | Props |
---|---|---|
内容类型 | 模板片段(HTML/组件) | 数据(字符串/数字/对象等) |
使用场景 | 结构定制 | 数据传递 |
作用域 | 可使用子组件数据(作用域插槽) | 父组件单向传递 |
动态性 | 高 | 中等 |
最佳实践建议
- 合理命名:使用语义化的插槽名称(如
#header
、#footer
) - 默认内容:为常用插槽提供合理的默认实现
- 作用域控制:当需要子组件数据时使用作用域插槽
- 适度使用:避免过度使用插槽导致组件结构复杂化
- 样式隔离:通过 CSS Scoped 或 BEM 规范管理插槽样式
通过以上方式,可以充分利用 Vue 的插槽机制,构建出高复用性、灵活可定制的组件体系,这在类似 JeecgBoot 这类需要高度可配置性的后台管理系统中尤为重要。