vue-iview可展开表格封装

好久不见. 提交于 2019-12-05 19:31:25

项目中我么有时候可以用到可以展开的表格树形表格,方便我们数据和层级关系。

效果图:

 

 

 实现方式:递归组件思路,使用iview的表格https://www.iviewui.com/components/table#KZK

封装的组件:

src/views/commonComponents/ExpandTable/ExpandTable.vue

<template>
    <div :class="['ExpandTable', 'ExpandTableLevel'+ lev, {'no-table-header': lev !== 1}]">
        <Table :class="['table', 'table-level-' + lev]" :loading="tableLoading" :columns="columnsIn" :data="tableData" @on-row-dblclick="handleRowDBclick"></Table>
    </div>
</template>

<script>
    // import util from '@/libs/util';
    import ExpandTable from './ExpandTable.vue';
    export default {
        name: 'ExpandTable',
        components: {ExpandTable},
        /**
         * @on-update-complete 数据更新完成的 事件 ,配合 update props 可以做到 表格数据筛选, 在这个时间内 把 update字段 更改未 false
         * */
        props: {
            //展开是接口
            api: String,
            // row: Object,
            //展开时上级Id 的字段名称
            parentIDFiled: {
                type: String,
                default: 'depId'
            },
            id: String,
            // beginDate: String,
            // endDate: String,
            //层级(使用时这个props不用传)
            level: {
                type: Number,
                default: 0
            },
            //固定的请求参数
            reqParam: {
                type: Object,
                default: ()=>({})
            },
            //表格列
            columns: {
                type: Array,
                default: ()=>([])
            },
            update: Boolean,  // false -> true  时更新 展开表格的数据
            /**
             * 处理接口响应数据的函数, 主要是对接口响应的列表数据挂载  _disableExpand 字段 -> 为true 禁用展开(不显示前面的 展开符号)
             * @return  此函数必须 返回 表格数据 处理后表格的数据
            * */

            handleResFun: {
                type: Function,
                required: true
            }
        },
        data(){
            return {
                lev: 1,
                tableLoading: false,
                tableData: [],
                columnsIn: [
                    {
                        type: 'expand',
                        width: 50,
                        render: (h, params) => {
                            return h(ExpandTable, {
                                props: {
                                    api: this.api,
                                    // id: params.row.depId,
                                    id: params.row[this.parentIDFiled],
                                    level: this.lev,
                                    // beginDate: this.beginDate,
                                    // endDate: this.endDate
                                    reqParam: this.reqParam,
                                    parentIDFiled: this.parentIDFiled,
                                    columns: this.columns,
                                    handleResFun: this.handleResFun
                                }
                            })
                        }

                    },
                    ...this.columns
                ]

            }
        },
        watch: {
            update(val){
                val && this.lev === 1 && (this.getTableOfData())
            }
        },
        methods: {
            //表格行双击   展开与折叠
            handleRowDBclick(row, index){
                //禁用状态不能展开
                if(row._disableExpand) return;
                if(this.tableData[index]['_expanded']){
                    this.$set(this.tableData[index], '_expanded', false);
                }else {
                    this.$set(this.tableData[index], '_expanded', true);
                }
            },

            //获取表格数据
            getTableOfData(){
                let that = this;
                this.tableLoading = true;
                this.$post(this.api, { [this.parentIDFiled]: this.id, ...this.reqParam }).then( response => {
                    if (response.success) {
/*
                        response.data.list.forEach(item=> {
                            //如果是人state '1'  count '0' 没有子项 禁用展开、
                            if( item.state === '1' || item.count === '0' ) item._disableExpand = true
                        });
                        that.tableData = response.data.list;
*/
                        that.tableData = this.handleResFun(response);
                    } else {
                        that.$Message.error(`查询失败:${response.msg}`);
                    }
                    that.tableLoading = false;
                    this.$emit('on-update-complete')
                }).catch(error => {
                    console.log('列表查询出错', error);
                });

            },

        },
        created() {
            this.lev = this.level + 1;
        },
        mounted () {
            // console.log(`显示第${this.lev}层数据`);
            this.getTableOfData();
        }
    };
</script>

<style scoped>
    .ExpandTable {
        background: #fff;
    }
    .ExpandTable >>> .table {
        border: none;
        margin-left: 30px;
    }

    .ExpandTable >>> .table .ivu-table-expanded-cell {
        background: #fff;
        padding: 0;
    }

    .ExpandTable.no-table-header >>> .table .ivu-table-header {
        display: none;
    }
    /*最外层边框*/
    .ExpandTableLevel1 >>> .table-level-1.ivu-table-wrapper {
        position: relative;
        border: 1px solid #dcdee2;
        border-bottom: 0;
        /*border-right: 0;*/
        overflow: hidden;
    }

    .ExpandTableLevel1 >>> .ivu-table-overflowX {
        overflow: unset;
    }

    .ExpandTableLevel1 >>> .table-level-1 {
        margin-left: 0;
    }


    /*所有子项下边线*/
    /*
        .ExpandTable >>> .table .ivu-table::before {
            height: 0;
        }
    */

    .ExpandTable >>> .table .ivu-table::after {
        width: 0;
    }

    .ExpandTable >>> .table .ivu-table td {
        border-bottom: none;
    }

</style>

 

使用时:src/views/storeshop/stat/timeLimitStat.vue

<template>
    <div class="timeLimitStat wrapper_box">
        <ExpandTable
                api="/pointStock/increment"
                parentIDFiled="depId"
                :columns="columns"
                :update="updateTable"
                :reqParam="{beginDate: formSearch.beginDate, endDate: formSearch.endDate}"
                :handleResFun="handleResDataFun"
                @on-update-complete="handleUpdateComplete"/>
    </div>
</template>

<script>
    import ExpandTable from '../../commonComponents/ExpandTable/ExpandTable';
    export default {
        name: 'timeLimitStat',
        inject: ['export'],
        components: { ExpandTable },
        data(){
            return {
                //展开层级
                // lev: 0,
                // tableData: [],
                //表格列定义
                columns: [
                    {
                        title: '部门',
                        key: 'depName',
                    },
                    {
                        title: '期初',
                        width: 400,
                        key: 'beginPoint',
                    },
                    {
                        title: '期末',
                        width: 400,
                        key: 'endPoint',
                    },
                    {
                        title: '增量',
                        width: 400,
                        key: 'beginPoint',
                        render: (h, params)=> h('span', Number(params.row.endPoint) - Number(params.row.beginPoint) )
                    },
                ],
                updateTable: false, //是否更新 展开表格的数据
            }
        },
        methods: { 
            // /pointStock/increment 接口数据处理函数
            handleResDataFun(response){
                response.data.list.forEach(item=> {
                    //如果是人state '1'  count '0' 没有子项 禁用展开、
                    if( item.state === '1' || item.count === '0' ) item._disableExpand = true
                });
                return response.data.list;
            },
            // 展开表格数据请求完毕的函数
            handleUpdateComplete(){
                this.updateTable = false;
            }
        },
        created(){
            this.computedTime(this.formSearch.timeArr);
        },
        mounted () {
        }
    };
</script>

<style scoped>
    .timeLimitStat >>> .ivu-table-expanded-cell {
        padding: 0;
    }
</style>

效果图:

 

 

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!