elementplus实现多级表格(最后一级展示图片)

 更新时间:2023年05月04日 08:30:21   作者: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 多级表格 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue实现点击当前标签高亮效果【推荐】

    vue实现点击当前标签高亮效果【推荐】

    这篇文章主要介绍了vue实现点击当前标签高亮效果的思路详解,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友参考下吧
    2018-06-06
  • 路由vue-route的使用示例教程

    路由vue-route的使用示例教程

    这篇文章主要介绍了路由vue-route的使用,本文结合示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-12-12
  • nuxt实现封装axios并且获取token

    nuxt实现封装axios并且获取token

    这篇文章主要介绍了nuxt实现封装axios并且获取token,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • Vuejs第八篇之Vuejs组件的定义实例解析

    Vuejs第八篇之Vuejs组件的定义实例解析

    这篇文章主要介绍了Vuejs第八篇之Vuejs组件的定义实例解析的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-09-09
  • Vant中Popover气泡弹出框位置错乱问题解决

    Vant中Popover气泡弹出框位置错乱问题解决

    这篇文章主要为大家介绍了Vant中Popover气泡弹出框位置错乱问题解决,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • Vue编译器optimize源码分析

    Vue编译器optimize源码分析

    这篇文章主要为大家介绍了Vue 编译器optimize源码分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • 第一次接触神奇的前端框架vue.js

    第一次接触神奇的前端框架vue.js

    第一次接触神奇的vue.js,主要了解一下v-model、v-if、v-else、v-show、v-for等,感兴趣的小伙伴们可以一起学习一下
    2016-12-12
  • vue如何通过button的disabled控制按钮能否被使用

    vue如何通过button的disabled控制按钮能否被使用

    这篇文章主要介绍了vue如何通过button的disabled控制按钮能否被使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-04-04
  • 详解如何在Vue项目中实现累加动画

    详解如何在Vue项目中实现累加动画

    这篇文章主要为大家详细介绍了如何在你的Vue项目中实现累加动画,文中的示例代码简洁易懂,具有一定的参考价值,感兴趣的小伙伴可以了解一下
    2023-06-06
  • vue bus全局事件中心简单Demo详解

    vue bus全局事件中心简单Demo详解

    ue-bus 提供了一个全局事件中心,并将其注入每一个组件,你可以像使用内置事件流一样方便的使用全局事件。这篇文章给大家介绍了vue bus全局事件中心简单Demo,需要的朋友参考下吧
    2018-02-02

最新评论