首页 > 其他分享 >vue3+element plus +js 实现树形和末级展开是表格

vue3+element plus +js 实现树形和末级展开是表格

时间:2024-11-11 10:58:21浏览次数:1  
标签:el const element v2 plus table 末级 data id

1、实现一个树形和末级展开是表格,需要支持大数据量,因此使用Virtualized Table 虚拟化表格 el-table-v2

2、效果图

 3、代码

<template>
    <el-table-v2 
        :header-height="0"
        v-model:expanded-row-keys="expandedRowKeys" 
        :columns="columns" 
        :data="treeData" 
        :width="1000"
        :expand-column-key="expandColumnKey" 
        :height="800" 
        :estimated-row-height="200" 
        @row-expand="onRowExpanded"
        @expanded-rows-change="onExpandedRowsChange">
        <template #row="props">
            <Row v-bind="props" />
            <div class="p-6" v-if="!props.rowData.children.length">
                <el-table :data="props.rowData.tableData" :height="200" style="width: 100%" border header-cell-class-name="table-header">
                    <el-table-column prop="name" label="文件名称" />
                    <el-table-column prop="size" label="文件大小" />
                    <el-table-column prop="date" label="上传日期" />
                    <el-table-column align="center" label="操作" width="80" >
                        <template #default="scope">
                            <el-icon @click="handleDownload(scope.$index, scope.row)"><Download /></el-icon>
                        </template>
                        </el-table-column>
                </el-table>
            </div>
            <div style="height: 50px;line-height: 50px;margin-left: 5px;">
                <el-button v-if="props.rowData.children.length" :icon="Download" type="primary" plain
                @click="handleDownload(null, props.rowData)"
                >下载目录</el-button>
            </div>
        </template>
    </el-table-v2>
</template>

<script setup>
import { computed, ref, createVNode as _createVNode2 } from 'vue'
import { TableV2FixedDir } from 'element-plus' 
import {Download} from '@element-plus/icons-vue'
const expandColumnKey = 'column-0'
const generateColumns = (length = 10, prefix = 'column-', props) =>
    Array.from({ length }).map((_, columnIndex) => ({
        ...props,
        key: `${prefix}${columnIndex}`,
        dataKey: `${prefix}${columnIndex}`,
        title: `Column ${columnIndex}`
    }))

const generateData = (
    columns,
    length = 200,
    prefix = 'row-'
) =>
    Array.from({ length }).map((_, rowIndex) => {
        return columns.reduce(
            (rowData, column, columnIndex) => {
                rowData[column.dataKey] = `文件文件文件文件文件${rowIndex}`
                return rowData
            },
            {
                id: `${prefix}${rowIndex}`,
                parentId: null,
            }
        )
    })

const columns = generateColumns(1).map((column, columnIndex) => {
    let fixed
    return { ...column, fixed }
})

const data = generateData(columns, 200)

for (let i = 0; i < 200; i++) {
    data.push(
        {
            ...data[i],
            id: `${data[i].id}-sub-${i}`,
            parentId: data[i].id,
            [expandColumnKey]: `202${i}`,
        },{
            ...data[i],
            id: `${data[i].id}-sub-sub-${i}`,
            parentId: `${data[i].id}-sub-${i}`,
            [expandColumnKey]: `Sub-202${i}`,
        }
    )
}
function unflatten(
    data,
    rootId = null,
    dataKey = 'id',
    parentKey = 'parentId'
) {
    const tree = []
    const childrenMap = {}

    for (const datum of data) {
        const item = { ...datum }
        const id = item[dataKey]
        const parentId = item[parentKey]

        if (Array.isArray(item.children)) {
            childrenMap[id] = item.children.concat(childrenMap[id] || [])
        } else if (!childrenMap[id]) {
            childrenMap[id] = []
        }
        item.children = childrenMap[id]
        if(!item.children.length){
            item.tableData = [
                    {
                        date: '2016-05-03',
                        name: 'Tom',
                        size: '18kb',
                    },
                    {
                        date: '2016-05-02',
                        name: 'Tom',
                        size: '18kb',
                    },
                    {
                        date: '2016-05-04',
                        name: 'Tom',
                        size: '18kb',
                    },
                    {
                        date: '2016-05-01',
                        name: 'Tom',
                        size: '108kb',
                    }
                ]
        }
        if (parentId !== undefined && parentId !== rootId) {
            if (!childrenMap[parentId]) childrenMap[parentId] = []
            childrenMap[parentId].push(item)
        } else {
            tree.push(item)
        }
    }
    return tree
}

const treeData = computed(() => unflatten(data))

const expandedRowKeys = ref([])

const onRowExpanded = ({ expanded }) => {
    console.log('Expanded:', expanded)
}

const onExpandedRowsChange = (
    expandedKeys
) => {
    console.log(expandedKeys)
}
const Row = ({
    cells,
    rowData
}) => {
    if (rowData.children.length) {
        return cells;
    }
}
const handleDownload = (index, row) => {
    console.log(index, row)
}
</script>

<style>
.el-table-v2{
    --el-table-border-color:none;
}
.el-table-v2__row-depth-0,
.el-table-v2__row-depth-1,
.el-table-v2__row-depth-2,
.el-table-v2__row-depth-3,
.el-table-v2__row-depth-4,
.el-table-v2__row-depth-5,
.el-table-v2__row-depth-6 {
    min-height: 50px;
}
.el-table-v2__row-cell{
    width: fit-content !important;
}
.el-table-v2__cell-text{
    height: 32px;
    min-width: 100px;
    line-height: 32px;;
    background-color: #F7F8FC;
    border: var(--el-border);
    border-color: #dcdfe6;
    padding: 0 15px;
    font-size: var(--el-font-size-base);
    border-radius: var(--el-border-radius-base);
    margin-top: 1px;
}
.el-table-v2__cell-text:hover {
    color: #409eff;
    border-color: #409eff;
    background-color: #ecf5ff;
}
.el-table-v2__cell-text::before {
    content: ''; 
    /* position: absolute;  */
    display: inline-block; 
    width: 16px;
    height: 16px; 
    margin-right: 5px;
    vertical-align: text-top;
    background-image: url('data:image/svg+xml;utf8,<svg data-v-d2e47025="" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path fill="grey" d="M878.08 448H241.92l-96 384h636.16l96-384zM832 384v-64H485.76L357.504 192H128v448l57.92-231.744A32 32 0 0 1 216.96 384zm-24.96 512H96a32 32 0 0 1-32-32V160a32 32 0 0 1 32-32h287.872l128.384 128H864a32 32 0 0 1 32 32v96h23.04a32 32 0 0 1 31.04 39.744l-112 448A32 32 0 0 1 807.04 896"></path></svg>'); /* 替换为你的 SVG Data URI */
    background-size: cover; /* 确保 SVG 图像覆盖整个伪元素区域 */
}
.el-table-v2__cell-text:hover::before {
    background-image: url('data:image/svg+xml;utf8,<svg data-v-d2e47025="" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path fill="CornflowerBlue" d="M878.08 448H241.92l-96 384h636.16l96-384zM832 384v-64H485.76L357.504 192H128v448l57.92-231.744A32 32 0 0 1 216.96 384zm-24.96 512H96a32 32 0 0 1-32-32V160a32 32 0 0 1 32-32h287.872l128.384 128H864a32 32 0 0 1 32 32v96h23.04a32 32 0 0 1 31.04 39.744l-112 448A32 32 0 0 1 807.04 896"></path></svg>'); /* 替换为你的 SVG Data URI */
}
.p-6 {
    margin:0 20px;
    width: 98%;
    height:200px;
}
.el-button:focus, .el-button:hover {
    color: var(--el-button-text-color);
    border-color: var(--el-button-hover-border-color);
    background-color: #ecf5ff;
    outline: 0;
}
.table-header{
    background-color: #F8F9FB !important;
}
</style>

 

标签:el,const,element,v2,plus,table,末级,data,id
From: https://www.cnblogs.com/aoshuang/p/18539298

相关文章

  • SQL注入攻击及其在SpringBoot中使用MyBatisPlus的防范策略
    SQL注入攻击及其在SpringBoot中使用MyBatisPlus的防范策略随着互联网技术的飞速发展,Web应用的安全问题日益凸显,其中SQL注入攻击是最常见的安全威胁之一。SQL注入攻击不仅可能导致敏感数据泄露,还可能引发数据篡改、服务中断等严重后果。本文将详细介绍SQL注入攻击的基本概念......
  • Vue2中使用Element-ui封装表单(el-form)组件动态渲染数据
    1.创建一个searchForm组件,将需要封装的searchForm组件全局注册,为了方便下次直接使用在main.js文件中全局注册importSearchFormfrom'./components/SearchForm'Vue.component('SearchForm',SearchForm)2.在searchForm组件中创建基本结构<template><divclass="ces-......
  • EPPlusExcel
     <ItemGroup><PackageReferenceInclude="EPPlus"Version="7.4.2"/></ItemGroup> usingOfficeOpenXml;namespaceEPPlusExcel{internalclassProgram{privatestaticvoidMain(string[]args)......
  • 【Mplus 8.7软件下载与安装教程】
     1、安装包Mplus8.7:链接:https://pan.quark.cn/s/128e81c51dbe提取码:1X7BMplus8.3:链接:https://pan.quark.cn/s/5ea5ff583480提取码:VdjtMplus7.4:链接:https://pan.quark.cn/s/414ec0c8cb14提取码:8jhm2、安装教程1)       双击Mplus8.7Demo(64-bit).msi安装......
  • 乌龟棋(琪露诺速冻青蛙plus版)
    洛谷乌龟棋与琪露诺速冻青蛙不同的是,移动某步长有次数限制。速冻青蛙由于没有次数限制,步数不用加入dp数组考虑。而乌龟棋步数有限制,以步数构建dp数组,位置可由dp数组计算出。#include<bits/stdc++.h>usingnamespacestd;longlongdp[41][41][41][41],n,m;inta[1000],b[5],c......
  • element-ui-plus给头像avatar增加头像框
    template部分:<el-avatarshape="square":size="50":fit="fit":src="avatarImg"class="avatar-with-border-image"/>style部分:.avatar-with-border-image{position:re......
  • 六、MyBatis-Plus高级用法(1):最优化持久层开发
    一、MyBatis-Plus快速入门1.1简介课程版本:3.5.3.1MyBatis-Plus......
  • 深入 MyBatis-Plus 插件:解锁高级数据库功能
    一、关于Mybatis-Plus插件1.1简介Mybatis-Plus提供了丰富的插件机制,这些插件可以帮助开发者更方便地扩展Mybatis的功能,提升开发效率、优化性能和实现一些常用的功能。​‍1.2实现原理Mybatis-Plus的插件实现是基于MyBatis的拦截器机制,这些插件通过MybatisPlusInte......
  • Vue3+ElementPlus快速入门 | 小蚂蚁云
       项目介绍基于SpringBoot3、SpringSecurity、MybatisPlus、Vue3、TypeScript、Vite、ElementPlus、MySQL等技术栈实现的单体前后端分离后台管理系统;后端基于Java语言采用SpringBoot3、SpringSecurity、MybatisPlus、MySQL等主流技术栈,前端基于Vue3、TypeScript、Vite等技......
  • MyBatis Plus之注解实现动态SQL
     参考下面的sql语句即可实现@Select("<script>"+"selectgp.TEWRTYR,gp.FJFNM,gs.CVNNN,u.VCNBMBNV,gp.RAEER,gr.BVNCCVN\n"+"fromUPPBHTu\n"+"leftjoinGP_testgp\n"+......