elementplus实现多级表格(最后一级展示图片)
短信预约 -IT技能 免费直播动态提醒
想要实现的效果
总共四级 前三级是表格 第四级使用图片展示; 看了一下官网 计划使用官网的树形结构, 但是发现并不能满足最后一个是图片形式的展示
最后利用了表格的expand;
在过程中主要需要解决的问题有:vue3 递归使用组件;递归处理数据;展开全部级。
递归处理数据
首先需要处理一下数据,把他们弄成字段一致的,如果后端处理过,前端也会需要处理一下,用于前端自己新增使用的字段 ,我这边 新增了三个字段
- disableExpand: 用于我的展开表格 单行能不能展开
- id: 后端没有给id字段 用于唯一标识
- level: 判断当前数据是第几级数据
const getOverviewList = async () => {
if (!searchParams.value.train_type_id) {
return;
}
const resp = await Pepper.get('/api/match/detail', {
params: searchParams.value
});
overviewTotal.value = resp.data.list.length;
overviewList.value = handleOverviewList(resp.data.list);
};
const handleOverviewList = (data: OverviewListModel[], listLevel = 1) => {
const result: OverviewListModel[] = data.map((item, index) => {
return {
...item,
// 新增字段
disableExpand: !!item.sub_number,
level: listLevel,
id: listLevel + '-' + index,
// 处理list
list: item.list && item.list.length ? handleOverviewList(item.list as OverviewListModel[], listLevel + 1) : []
};
});
return result;
};
递归调用组件
因为字段一致所以我使用的是同一个组件,需要说明的是 vue3使用自己组件的时候直接使用即可
在外层:传入所有的data
<overview-table
ref="overviewTableRef"
:total="overviewTotal"
:data="overviewList"
/>
在OverviewTable组件中 直接使用OverviewTable就可;下面这个包括展开所有级的代码
展开所有级 利用@expand=“handleExpand” 修改expandKeys即可
<template>
<div>
<expand-table
ref="tableRef"
:data="data"
:total="total"
:pageParams="pageParams"
v-model:expandRowKeys="expandKeys"
v-bind="$attrs"
@oneClick="rowClick"
@expand="handleExpand"
>
<template #expand="{ row }">
<overview-table
:ref="el => setOverviewDetailRef(el, row.id)"
v-if="row.level !== 3"
:data="row.list"
:total="row.list.length"
:show-header="false"
:height="2000"
:table-level="row.level + 1"
/>
<overview-table-detail
v-else
:data="row.list"
@openDialog="openDialog"
/>
</template>
<el-table-column
prop="name"
min-width="10%"
label="数据类型"
/>
....
<el-table-column
prop="sub_number"
min-width="10%"
label="包含下级数"
>
<template #default="{ row }">
<span :class="!row.sub_number ? 'no-sub' : ''">{{ row.sub_number }}</span>
</template>
</el-table-column>
<operation-column
min-width="10%"
:operationOptions="operationOptions"
/>
</expand-table>
<image-detail-dialog
:showDeleteBtn="false"
ref="imageDetailDialogRef"
/>
</div>
</template>
<script setup lang="ts">
import { computed, ref, inject, nextTick } from 'vue';
import ExpandTable from '@/components/table/ExpandTable.vue';
import OverviewTableDetail from './OverviewTableDetail.vue';
import ImageDetailDialog from '../../original/stop/ImageDetailDialog.vue';
import OperationColumn, { OperationOptionModel } from '@/components/table/OperationColumn.vue';
import { PageAware } from '@/model';
import { ConfigModel } from 'public/config';
import { OverviewListModel } from '@/model/registration';
import { PhotoListModel } from '@/model/original';
const props = withDefaults(
defineProps<{
data: OverviewListModel[];
total: number;
tableLevel?: number;
}>(),
{
data: () => [],
tableLevel: 1
}
);
const pageParams = ref<PageAware>({
page_no: 1,
page_size: (inject('global') as ConfigModel).registration.registrationLimit
});
const tableRef = ref<InstanceType<typeof ExpandTable>>();
const overviewDetailRefs = ref<any>({});
const imageDetailDialogRef = ref<InstanceType<typeof ImageDetailDialog>>();
const expandKeys = ref<string[]>([]);
const operationOptions = computed<OperationOptionModel[]>(() => {
return [
{
icon: 'icon-upload',
title: '上传',
hidden: props.tableLevel !== 1,
onClick: () => {}
},
{
icon: 'icon-compute',
title: '计算',
hidden: props.tableLevel !== 2,
disabled: (row: OverviewListModel) => {
return row.state !== '待计算';
},
onClick: () => {}
}
];
});
// 动态ref
const setOverviewDetailRef = (el: any, id: number) => {
if (el) {
overviewDetailRefs.value[id] = el;
}
};
// 打开弹窗
const openDialog = (index: any, data: PhotoListModel[]) => {
imageDetailDialogRef.value?.open(index, data);
};
// 单击展开/关闭
const rowClick = (row: OverviewListModel) => {
if (expandKeys.value.includes(row.id)) {
tableRef.value?.closeRowExpansion(row);
} else {
expandKeys.value.push(row.id);
}
};
// 展开全部
const handleExpand = (ids: number[] | string[]) => {
// 情况1:一级全部展开 点击其他的时候 只展开下一级
// const handleExpand = (ids: number[] | string[], autoExpand) => {
// autoExpand.value = autoExpandEd ? autoExpandEd : props.tableLevel === 1;
// if (!autoExpand.value) {
// return;
// }
// 情况3:点击一级 只展开到三级
// if (props.tableLevel !== 1) {
// return;
// }
ids.forEach(async id => {
await nextTick();
const stopOverviewDetailRef = overviewDetailRefs.value[id];
if (stopOverviewDetailRef) {
await stopOverviewDetailRef?.openRowExpansion();
}
});
};
const openRowExpansion = () => {
//情况1:一级全部展开 点击其他的时候 只展开下一级
// const ids = (props.data as OverviewListModel[]).map(i => i.id);
// handleExpand(ids, true);
// 情况2:点击任何一级 他下面的都展开
props.data.map(item => {
if (!item.disableExpand) {
return;
}
if (!expandKeys.value.includes(item.id)) {
expandKeys.value.push(item.id);
}
});
};
const reset = () => {
// 重新搜索的时候 关闭展开的
tableRef.value?.closeAllExpand();
expandKeys.value = [];
};
defineExpose({
reset,
expandKeys,
openRowExpansion
});
</script>
<style lang="scss" scoped>
:deep(.el-table__expanded-cell[class*='cell']) {
padding: 0;
}
:deep(.el-button + .el-button) {
margin-left: 0;
}
.no-sub {
color: #b9bdc9;
}
// 防止弹框样式有问题
:deep(.el-table .el-table__row) {
position: relative;
z-index: 0;
}
</style>
到此这篇关于elementplus 实现多级表格 最后一级展示图片的文章就介绍到这了,更多相关elementplus 多级表格 内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341