DdLevelTable 层级表格组件
组件介绍
DdLevelTable是一个基于Element UI封装的层级表格组件,专门用于展示具有父子关系的数据结构(如分类层级、部门结构等)。该组件在标准表格功能基础上,增加了层级数据展示、递归渲染和父子节点关联操作等特性,同时支持分页、权限控制和自定义操作按钮。
基本用法
<dd-level-table
ref="table"
:list="list"
:total="total"
row-key="category_id"
:list-loading="listLoading"
:columns="tableColumns"
:list-query="filterInfo.data"
@getList="getList"
:auth="auth"
@handleSelectionChange="handleSelectionChange"
:show-excel-export="false"
:show-excel-import="false"
@handleCreate="handleCreate"
>
<!-- 自定义插槽内容 -->
</dd-level-table>
属性说明
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| list | Array | [] | 表格数据数组 |
| total | Number | 0 | 数据总条数(用于分页) |
| row-key | String | 'id' | 行数据的唯一标识字段 |
| list-loading | Boolean | false | 加载状态指示器 |
| columns | Array | [] | 列配置信息 |
| list-query | Object | {} | 分页和查询参数 |
| auth | Object | {} | 权限控制对象 |
| show-excel-export | Boolean | true | 是否显示导出按钮 |
| show-excel-import | Boolean | true | 是否显示导入按钮 |
| border | Boolean | true | 是否显示表格边框 |
| stripe | Boolean | true | 是否显示斑马纹 |
| size | String | 'medium' | 表格尺寸,可选值:'medium'/'small'/'mini' |
| pagination | Boolean | true | 是否显示分页控件 |
| page-size | Number | 20 | 每页显示条数 |
| current-page | Number | 1 | 当前页码 |
事件说明
| 事件名 | 参数 | 说明 |
|---|---|---|
| getList | - | 加载数据事件,用于分页和查询 |
| handleSelectionChange | val | 选择项变化事件 |
| handleCreate | - | 创建按钮点击事件 |
| row-click | row, event, column | 行点击事件 |
| cell-click | row, column, cell, event | 单元格点击事件 |
| sort-change | { column, prop, order } | 排序变化事件 |
层级数据展示
1. 数据结构要求
层级表格需要特定的数据结构来表示父子关系:
// 示例数据结构
[{
category_id: 1,
name: '顶级分类',
parent_id: 0,
children: [{
category_id: 2,
name: '二级分类',
parent_id: 1,
children: [{
category_id: 3,
name: '三级分类',
parent_id: 2
}]
}]
}]
2. 列配置示例
tableColumns: [
{ label: '分类名称', prop: 'name' },
{ label: '上级分类', prop: 'parent_id' },
{ label: '分类图片', prop: 'image_id', slot: 'image_id' },
{ label: '排序', prop: 'sort' },
{ label: '操作', slot: 'action', fixed: 'right', width: 200 }
]
自定义插槽
1. 图片展示插槽
<template slot="image_id" slot-scope="{ row }">
<el-image style="width:80px; height: 80px" :src="row.image_id" />
</template>
2. 操作按钮插槽
<template slot="action" slot-scope="{ row, index }">
<dd-button
type="primary"
size="mini"
style="margin-right: 10px"
@click="amend(row, index)"
icon="el-icon-edit"
content="编辑"
circle
></dd-button>
<el-popconfirm
confirm-button-text="确认"
cancdd-button-text="取消"
icon="el-icon-info"
icon-color="red"
title="确认删除吗?"
@confirm="delectRow(row, index)"
>
<dd-button
slot="reference"
:auth="auth.delete"
content="删除"
type="danger"
size="mini"
icon="el-icon-delete"
circle
></dd-button>
</el-popconfirm>
</template>
权限控制
通过auth属性实现按钮级别的权限控制:
<dd-level-table :auth="auth">
<!-- 操作按钮 -->
<dd-button :auth="auth.delete" ... ></dd-button>
</dd-level-table>
权限对象结构示例:
data() {
return {
auth: {
delete: true,
edit: true,
// 其他权限...
}
}
}
分页实现
1. 分页参数绑定
<dd-level-table
:list-query="filterInfo.data"
@getList="getList"
>
</dd-level-table>
2. 分页数据处理
data() {
return {
filterInfo: {
filter: {
page: 1,
pageSize: 20,
name: '',
// 其他查询参数
}
},
total: 0,
list: []
}
},
methods: {
getList() {
const that = this
that.listLoading = true
// 调用API获取数据
searchCategory(this.filterInfo.filter).then((res) => {
that.total = res.data.length;
that.list = res.data;
that.listLoading = false;
});
}
}
完整示例
结合分类管理的完整层级表格实现:
<template>
<div class="app-container">
<!-- 检索区域 -->
<el-filter
size="medium"
:data="filterInfo.data"
:field-list="filterInfo.fieldList"
:show-selection="false"
@handleFilter="handleFilter"
@handleReset="handleReset"
@handleEvent="handleEvent"
/>
<!-- 层级表格 -->
<dd-level-table
ref="table"
:list="list"
:total="total"
row-key="category_id"
:list-loading="listLoading"
:columns="tableColumns"
:list-query="filterInfo.data"
@getList="getList"
:auth="auth"
@handleSelectionChange="handleSelectionChange"
:show-excel-export="false"
:show-excel-import="false"
@handleCreate="handleCreate"
>
<!-- 图片展示插槽 -->
<template slot="image_id" slot-scope="{ row }">
<el-image style="width:80px; height: 80px" :src="row.image_id" />
</template>
<!-- 操作按钮插槽 -->
<template slot="action" slot-scope="{ row, index }">
<dd-button
type="primary"
size="mini"
style="margin-right: 10px"
@click="amend(row, index)"
icon="el-icon-edit"
content="编辑"
circle
></dd-button>
<el-popconfirm
confirm-button-text="确认"
cancdd-button-text="取消"
icon="el-icon-info"
icon-color="red"
title="确认删除吗?"
@confirm="delectRow(row, index)"
>
<dd-button
slot="reference"
:auth="auth.delete"
content="删除"
type="danger"
size="mini"
icon="el-icon-delete"
circle
></dd-button>
</el-popconfirm>
</template>
</dd-level-table>
<!-- 表单弹窗 -->
<list-form
:params="formObj.params"
:type="formObj.type"
:title="formObj.title"
:dialogVisible="formObj.dialogVisible"
@update:dialogVisible="listFormClose"
/>
</div>
</template>
<script>
export default {
data() {
return {
auth: auth,
formObj: {
type: null,
title: '分类管理',
dialogVisible: false,
params: {}
},
filterInfo: {
filter: {
page: 1,
pageSize: 20,
name: ''
},
fieldList: [
{ label: '分类名称', type: 'input', value: 'name' }
]
},
tableColumns: [
{ label: '分类名称', prop: 'name' },
{ label: '上级分类', prop: 'parent_id' },
{ label: '分类图片', prop: 'image_id', slot: 'image_id' },
{ label: '排序', prop: 'sort' },
{ label: '操作', slot: 'action', fixed: 'right', width: 200 }
],
total: 0,
list: [],
listLoading: false
}
},
created() {
this.getList()
},
methods: {
getList() {
const that = this
that.listLoading = true
searchCategory(this.filterInfo.filter).then((res) => {
that.total = res.data.length;
that.list = res.data;
that.listLoading = false;
});
},
handleFilter(row) {
this.filterInfo.filter = row
this.getList()
},
amend(row) {
// 编辑操作
},
delectRow(row) {
// 删除操作
},
handleCreate() {
// 创建操作
}
}
}
</script>
注意事项
- 层级表格需要正确设置
row-key属性以确保数据正确渲染 - 父子关系数据通过
children属性嵌套表示 - 分页参数需要与后端API要求保持一致
- 权限控制需要在组件内部和按钮级别同时设置
- 自定义插槽中的操作按钮事件需要在父组件中实现
高级特性
1. 动态加载子节点
支持异步加载子节点数据,适用于大数据量场景
2. 拖拽排序
支持行内拖拽实现层级和顺序调整
3. 展开/折叠控制
提供默认的展开/折叠功能,可通过属性控制默认状态
常见问题
Q: 如何自定义层级缩进? A: 通过CSS变量
--level-indent自定义缩进量Q: 如何默认展开特定层级? A: 设置
default-expand-all属性为true,或使用expand-row-keys指定展开的行IDQ: 分页不生效怎么办? A: 确保
list-query中包含正确的分页参数,并且getList方法正确处理分页逻辑
