elementplus實(shí)現(xiàn)多級表格(最后一級展示圖片)
想要實(shí)現(xiàn)的效果

總共四級 前三級是表格 第四級使用圖片展示; 看了一下官網(wǎng) 計(jì)劃使用官網(wǎng)的樹形結(jié)構(gòu), 但是發(fā)現(xiàn)并不能滿足最后一個(gè)是圖片形式的展示
最后利用了表格的expand;
在過程中主要需要解決的問題有:vue3 遞歸使用組件;遞歸處理數(shù)據(jù);展開全部級。
遞歸處理數(shù)據(jù)
首先需要處理一下數(shù)據(jù),把他們弄成字段一致的,如果后端處理過,前端也會需要處理一下,用于前端自己新增使用的字段 ,我這邊 新增了三個(gè)字段
- disableExpand: 用于我的展開表格 單行能不能展開
- id: 后端沒有給id字段 用于唯一標(biāo)識
- level: 判斷當(dāng)前數(shù)據(jù)是第幾級數(shù)據(jù)
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;
};遞歸調(diào)用組件
因?yàn)樽侄我恢滤晕沂褂玫氖峭粋€(gè)組件,需要說明的是 vue3使用自己組件的時(shí)候直接使用即可
在外層:傳入所有的data
<overview-table
ref="overviewTableRef"
:total="overviewTotal"
:data="overviewList"
/>在OverviewTable組件中 直接使用OverviewTable就可;下面這個(gè)包括展開所有級的代碼
展開所有級 利用@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="數(shù)據(jù)類型"
? ? ? />
? ? ? ....
? ? ? <el-table-column
? ? ? ? prop="sub_number"
? ? ? ? min-width="10%"
? ? ? ? label="包含下級數(shù)"
? ? ? >
? ? ? ? <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: '計(jì)算',
? ? ? hidden: props.tableLevel !== 2,
? ? ? disabled: (row: OverviewListModel) => {
? ? ? ? return row.state !== '待計(jì)算';
? ? ? },
? ? ? onClick: () => {}
? ? }
? ];
});
// 動態(tài)ref
const setOverviewDetailRef = (el: any, id: number) => {
? if (el) {
? ? overviewDetailRefs.value[id] = el;
? }
};
// 打開彈窗
const openDialog = (index: any, data: PhotoListModel[]) => {
? imageDetailDialogRef.value?.open(index, data);
};
// 單擊展開/關(guān)閉
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:一級全部展開 點(diǎn)擊其他的時(shí)候 只展開下一級
? // const handleExpand = (ids: number[] | string[], autoExpand) => {
? // autoExpand.value = autoExpandEd ? autoExpandEd : props.tableLevel === 1;
? // if (!autoExpand.value) {
? // ? return;
? // }
? // ?情況3:點(diǎn)擊一級 只展開到三級
? // if (props.tableLevel !== 1) {
? // ? return;
? // }
? ids.forEach(async id => {
? ? await nextTick();
? ? const stopOverviewDetailRef = overviewDetailRefs.value[id];
? ? if (stopOverviewDetailRef) {
? ? ? await stopOverviewDetailRef?.openRowExpansion();
? ? }
? });
};
const openRowExpansion = () => {
? //情況1:一級全部展開 點(diǎn)擊其他的時(shí)候 只展開下一級
? // const ids = (props.data as OverviewListModel[]).map(i => i.id);
? // handleExpand(ids, true);
? // 情況2:點(diǎn)擊任何一級 他下面的都展開
? props.data.map(item => {
? ? if (!item.disableExpand) {
? ? ? return;
? ? }
? ? if (!expandKeys.value.includes(item.id)) {
? ? ? expandKeys.value.push(item.id);
? ? }
? });
};
const reset = () => {
? // 重新搜索的時(shí)候 關(guān)閉展開的
? 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>到此這篇關(guān)于elementplus 實(shí)現(xiàn)多級表格 最后一級展示圖片的文章就介紹到這了,更多相關(guān)elementplus 多級表格 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue實(shí)現(xiàn)點(diǎn)擊當(dāng)前標(biāo)簽高亮效果【推薦】
這篇文章主要介紹了vue實(shí)現(xiàn)點(diǎn)擊當(dāng)前標(biāo)簽高亮效果的思路詳解,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2018-06-06
nuxt實(shí)現(xiàn)封裝axios并且獲取token
這篇文章主要介紹了nuxt實(shí)現(xiàn)封裝axios并且獲取token,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10
Vant中Popover氣泡彈出框位置錯(cuò)亂問題解決
這篇文章主要為大家介紹了Vant中Popover氣泡彈出框位置錯(cuò)亂問題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06
vue如何通過button的disabled控制按鈕能否被使用
這篇文章主要介紹了vue如何通過button的disabled控制按鈕能否被使用,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04
詳解如何在Vue項(xiàng)目中實(shí)現(xiàn)累加動畫
這篇文章主要為大家詳細(xì)介紹了如何在你的Vue項(xiàng)目中實(shí)現(xiàn)累加動畫,文中的示例代碼簡潔易懂,具有一定的參考價(jià)值,感興趣的小伙伴可以了解一下2023-06-06

