【element-ui】el-table子级表格懒加载

本文介绍了如何在Vue中使用el-table组件处理具有多层父子级结构的表格数据,实现点击父级行时懒加载子级表格,以及同级别之间的手风琴模式效果。通过操作DOM元素和利用el-table的事件处理函数,实现了动态加载和层级管理。
摘要由CSDN通过智能技术生成

需求:表格存在多层父子级结构,要求点击父级行任意处都可以实时加载子级表格,并且只有最末一层子级可点击跳转,同级别的展开模式为手风琴模式❗❗(有点抽象的效果图如下所示:

思路:灵机一动😄这不就是量身打造的树形结构懒加载!只有有两个小点有些tricky:1)通过直接获取箭头的DOM元素来给整行响应点击事件;2)利用el-table展开行的回调expanded-change手动变为手风琴模式,即某行展开之后,同级别的其他行变为收起状态

渲染代码如下:

// ⚠树形结构的el-table必须存在row-key属性,父子级结构需存在相同的row-key绑定字段
<el-table
        :key="Math.random()"
        ref="table_1"
        :data="tableData1"
        row-key="acc_code"
        @row-click="showVoucher"
        lazy
        :load="loadNext"
        :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
        @expand-change="toggleRow"
>
    <el-table-column
            label="科目"
            :show-overflow-tooltip="true"
            :resizable="false"
            min-width="200"
           >
        <template slot-scope="scope">
            <span v-if="scope.row.idepth == '-1'">
                <span class="has_underline" v-if="!scope.row.hasChildren">{{convertToChinaNum(scope.row.acc_code)}}、{{scope.row.acc_name}}</span>
                <span v-else>{{convertToChinaNum(scope.row.acc_code)}}、{{scope.row.acc_name}}</span>
            </span>
            <span v-else>
                <span class="has_underline" v-if="!scope.row.hasChildren">{{scope.row.acc_code}}-{{scope.row.acc_name}}</span>
                <span v-else>{{scope.row.acc_code}}-{{scope.row.acc_name}}</span>
            </span>
        </template>
    </el-table-column>
    <el-table-column
            label="年初余额"
            prop=""
            align="right"
            width="150">
    </el-table-column>
    <el-table-column label="当月" align="center">
        <el-table-column
                prop=""
                label="借方金额"
                :show-overflow-tooltip="true"
                :resizable="false"
                align="right"
                width="150">
        </el-table-column>
        <el-table-column
                prop=""
                label="贷方金额"
                :show-overflow-tooltip="true"
                :resizable="false"
                align="right"
                width="150px">
        </el-table-column>
    </el-table-column>
    <el-table-column label="累计" align="center">
        <el-table-column
                prop=""
                label="借方金额"
                :show-overflow-tooltip="true"
                :resizable="false"
                align="right"
                width="150px">
        </el-table-column>
        <el-table-column
                prop=""
                label="贷方金额"
                :show-overflow-tooltip="true"
                :resizable="false"
                align="right"
                width="150px">
        </el-table-column>
    </el-table-column>
    <el-table-column
            label="当月余额"
            prop=""
            width="150"
            align="right">
    </el-table-column>
</el-table>

主要逻辑代码如下:

// 加载父级基础数据
loadExpCounts(){
    axios({
        method: 'post', url: '/',
        data: '...',
    }).then(response => {
        let resp = response.data;
        if(resp.success){
            let exp_typeList = resp.objectMap.expTypeList || [];     
            this.tableData1 = exp_typeList;
            this.tableData1.forEach(exp=>{
                // 关闭所有子节点
                this.$refs.table_1.toggleRowExpansion(exp, false);
                // 判断是否存在子级
                if(exp.leaf_flag !== '1'){
                    this.$set(exp, 'hasChildren', true);
                }
            })
        }else{
            // ...
        }
    }).catch(error=> { }).finally(()=>{ });
},
// 懒加载下级表格
loadNext(tree, treeNode, resolve) {
    axios({
        method: 'post', url: '/',
        data: {
            ajax: true, act: '', exp_type:tree.acc_code,
        },
    }).then(response => {
        let resp = response.data;
        if(resp.success){
            let expList = resp.objectMap.expList || [];
            expList.forEach(exp=>{
                if(exp.leaf_flag !== '1'){
                    this.$set(exp, 'hasChildren', true);
                }
            });
            resolve(expList);
        }else{}
    }).catch(error=> {});
},

1、行点击事件

// 行点击触发
showVoucher(row, column, event){
    if(!row.hasChildren){
        // 进入详情页
        window.location = '...';
    } else {
        // 展开下一级
        event.currentTarget.querySelector('.el-table__expand-icon').click();
    }
},

2、同级别手风琴模式

// 手风琴模式
toggleRow(row, expanded){
    const rowId = row.acc_code;
    const rowLevel = row.idepth;     // 层级
    if (!expanded) {
        return;
    }
    let list = this.levelData.get(rowLevel);
    if (!list) {
        list = [];
    }
    list.push(row);                  // 同层级存入
    this.levelData.set(rowLevel, list);
    list.map(list => {
        if (list.acc_code !== rowId) {
            // 关闭同层级的其他行
            this.$refs.table_1.toggleRowExpansion(list, false);
        }
    });
},

3、数字转中文汉字【来自网友记录一下❗】

// 数字转汉字
convertToChinaNum(num) {
    let arr1 = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
    let arr2 = ['', '十', '百', '千', '万', '十', '百', '千', '亿', '十', '百', '千','万', '十', '百', '千','亿'];              // 可继续追加更高位转换值
    if(!num || isNaN(num)){
        return "零";
    }
    let english = num.toString().split("");
    let result = "";
    for (let i = 0; i < english.length; i++) {
        let des_i = english.length - 1 - i;   // 倒序排列设值
        result = arr2[i] + result;
        let arr1_index = english[des_i];
        result = arr1[arr1_index] + result;
    }
    result = result.replace(/零(千|百|十)/g, '零').replace(/十零/g, '十');
    result = result.replace(/零+/g, '零');
    result = result.replace(/零亿/g, '亿').replace(/零万/g, '万');
    result = result.replace(/亿万/g, '亿');
    result = result.replace(/零+$/, '');
    result = result.replace(/^一十/g, '十');
    return result;
},

至此大功告成😉 

  • 21
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值