elementplus实现多级表格(最后一级展示图片)
作者:xiaaaa.z
本文主要介绍了elementplus实现多级表格(最后一级展示图片),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
想要实现的效果
总共四级 前三级是表格 第四级使用图片展示; 看了一下官网 计划使用官网的树形结构, 但是发现并不能满足最后一个是图片形式的展示
最后利用了表格的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 多级表格 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!