美文网首页
ElementUI 树转表格-----跨行跨列(二)

ElementUI 树转表格-----跨行跨列(二)

作者: Cherry丶小丸子 | 来源:发表于2021-02-08 17:30 被阅读0次
demo.png
<div id="app">
    <el-table :data="tableData" border size="mini" :span-method="tableSpanMethod">
        <el-table-column align="center" prop="index1" label="资料类型"></el-table-column>
        <el-table-column align="center" prop="index2" label="资料名称"></el-table-column>
        <el-table-column align="center" prop="index3" label="资料内容"></el-table-column>
        <el-table-column align="center" prop="jurisdiction" label="权限">
            <template slot-scope="scope">
                <el-checkbox
                    v-for="(item, index) of scope.row.jurisdiction"
                    :key="item.id"
                    @change="changeShowStatus(item)"
                    :value="item.checked"
                    :label="item.label">
                </el-checkbox>
            </template>
        </el-table-column>
    </el-table>
</div>
<script>
    export default {
        data(){
            return {
                tableData:[],
                testData:[{
                    id: "13",
                    pId: "0",
                    label: "通用资料",
                    children: [{
                        id: "14",
                        pId: "13",
                        label: "政策依据",
                        children: [{
                            id: "801",
                            pId: "14",
                            label: "下载权限",
                            checked: false,
                            children: []
                        },{
                            id: "802",
                            pId: "14",
                            checked: false,
                            label: "预览权限",
                            children: []
                        }],
                    }],
                },{
                    id: "1",
                    pId: "0",
                    label: "宣传资料",
                    children: [{
                        id: "2",
                        pId: "1",
                        label: "产品宣传",
                        children: [{
                            id: "8",
                            pId: "2",
                            label: "宣传计划",
                            children:[{
                                id: "804",
                                pId: "8",
                                label: "下载权限",
                                checked: false,
                                children: []
                            },{
                                id: "806",
                                pId: "8",
                                label: "预览权限",
                                checked: false,
                                children: []
                            }]
                        },{
                            id: "9",
                            pId: "2",
                            label: "白皮书",
                            children: [{
                                id: "803",
                                pId: "9",
                                label: "下载权限",
                                checked: false,
                                children: []
                            },{
                                id: "805",
                                pId: "9",
                                label: "预览权限",
                                checked: false,
                                children: []
                            }]
                        },{
                            id: "10",
                            pId: "2",
                            label: "宣传册",
                            children: [{
                                id: "807",
                                pId: "10",
                                label: "下载权限",
                                checked: false,
                                children: []
                            },{
                                id: "808",
                                pId: "10",
                                label: "预览权限",
                                checked: false,
                                children: []
                            }],
                        },{
                            id: "11",
                            pId: "2",
                            label: "微信",
                            children: [{
                                id: "809",
                                pId: "11",
                                label: "查看权限",
                                checked: false,
                                children: []
                            }]
                        },{
                            id: "12",
                            pId: "2",
                            label: "期刊",
                            children: [{
                                id: "810",
                                pId: "12",
                                label: "下载权限",
                                checked: false,
                                children: []
                            },{
                                id: "811",
                                pId: "12",
                                checked: false,
                                label: "预览权限",
                                children: []
                            }]
                        }],
                    },{
                        id: "3",
                        pId: "1",
                        label: "产品PPT",
                        children: [{
                            id: "812",
                            pId: "3",
                            label: "下载权限",
                            checked: false,
                            children: []
                        },{
                            id: "813",
                            pId: "3",
                            checked: false,
                            label: "预览权限",
                            children: []
                        }]
                    },{
                        id: "4",
                        pId: "1",
                        label: "产品视频",
                        children: [{
                            id: "814",
                            pId: "4",
                            label: "下载权限",
                            checked: false,
                            children: []
                        },{
                            id: "815",
                            pId: "4",
                            label: "预览权限",
                            checked: false,
                            children: []
                        }]
                    }],
                },{
                    id: "5",
                    pId: "0",
                    label: "演示资料",
                    children: [{
                        id: "6",
                        pId: "5",
                        label: "产品界面截图",
                        children: [{
                            id: "816",
                            pId: "6",
                            label: "下载权限",
                            checked: false,
                            children: []
                        },{
                            id: "817",
                            pId: "6",
                            label: "预览权限",
                            checked: false,
                            children: []
                        }]
                    },{
                        id: "7",
                        pId: "5",
                        label: "演示环境",
                        children: [{
                            id: "819",
                            pId: "7",
                            label: "查看权限",
                            checked: false,
                            children: []
                        }]
                    }]
                }],
                getMaxFloorNum: 0,
            }
        },
        mounted() {
            // 抽离 最后一级节点
            let lastChildNode = this.getLastChildNode(JSON.parse(JSON.stringify(this.testData)));
            // 需要一个有且只有一个根节点的数据(如果返回的数据有且只有一个根节点,可省略此步骤)
            let obj = {
                id: '',
                pId: '',
                label: '',
                children: this.deleteSourceNode(this.testData) // 删除 最后一级节点
            }
            // 将 树结构数据 格式化为二维数组
            let formatArr = this.parseTreeToRow(obj);
            // console.log(formatArr)

            // 再将其格式化为一维数组(ElementUi 表格所需要的数据格式)
            let tableData = [];
            if (formatArr[0].length != 0) {
                formatArr.map((item, index) => {
                    let pushObj = { number : index + 1 }; // 添加索引值(列 序号),如不需要,则设置为空对象
                    item.map((itemb, indexb) => {
                        // 动态添加 指标列数据 对应 表头 prop 属性值
                        pushObj['index' + (indexb + 1)] = itemb.label;
                        // 添加 表格行数据 id (取的是最后一个children的 id 值)
                        if (indexb == item.length - 1) {
                            pushObj.id = itemb.id;
                        };
                    });
                    tableData.push(pushObj)
                });
            }
            // console.log(tableData)

            // 获取树结构最深层级数
            this.getMaxFloorNum = this.getMaxFloor(this.testData);

            // 未达到最深层级数节点 补充数据空缺
            for (let i = 0; i < tableData.length; i++) {
                for (let j = 0; j < this.getMaxFloorNum; j++) {
                    if (tableData[i]['index' + (j + 1)] == undefined) {
                        tableData[i]['index' + (j + 1)] = tableData[i]['index' + j];
                    }
                }
            }
            // 将抽离的最后一级节点 插入到 一维数组
            tableData.map((item, index) => {
                item.jurisdiction = lastChildNode[index]
            });
            // console.log(tableData)

            this.tableData = tableData;
        },
        created() {

        },
        methods:{
            /**
             * 合并行或列的计算方法
             */
            tableSpanMethod({row, column, rowIndex, columnIndex}){
                return {
                    rowspan: this.mergeRows(row[column.property], this.tableData, rowIndex, column.property),
                    colspan: columnIndex > 0 ? this.mergeCells(row[column.property], row, column.property, this.getMaxFloorNum) : 1
                };
            },
            /**
             * 递归-----取出树组件最后子节点
             * @param {Object} node      树的源数据
             * @returns {Object} temp    取出树组件最后子节点的集合
             */
            getLastChildNode(node, temp = []) {
                let forFn = (arr) => {
                    for (let i = 0; i < arr.length; i++) {
                        if (!arr[i].children || arr[i].children.length == 0) {
                            temp.push(arr);
                            arr = [];
                        } else {
                            forFn(arr[i].children)
                        }
                    }
                }
                forFn(node)
                return temp;
            },
            /**
             * 递归-----删除树组件源数据的最后子节点
             * @param {Object} node      树的源数据
             * @returns {Object} node    删除最后子节点之后的树的数据
             */
            deleteSourceNode(node) {
                for (let i = node.length - 1; i >= 0; i--) {
                    if (!node[i].hasOwnProperty('children')) {
                        continue;
                    }
                    if (!node[i].children || node[i].children.length == 0) {
                        node.splice(i, 1);
                        continue;
                    }
                    this.deleteSourceNode(node[i].children);
                }
                return node;
            },
            /**
             * 递归-----将树结构数据格式,转化为 二维数组 表格形式
             * @param node  树的源数据
             * @param data  树转化为二维数组的数据
             * @param row   临时存储数据
             * @returns {*[]}
             */
            parseTreeToRow(node, data = [], row = []) {
                if (!node.children || node.children.length == 0) {
                    data.push(row);
                } else {
                    node.children.map((item, index) => {
                        const obj = {
                            id: item.id,
                            pId: item.pId,
                            label: item.label
                        };
                        this.parseTreeToRow(item, data, [...row, obj]);
                    });
                }
                return data;
            },
            /**
             * 递归-----树形数据(数组)获取最深层级数
             * @param {Object} treeData    树的源数据
             * @returns {Number}           最深层级数的值
             */
            getMaxFloor(treeData) {
                let floor = 0;
                let max = 0;
                let deepEach = (data, floor) => {
                    data.map((item, index) => {
                        item.floor = floor;
                        if (floor > max) {
                            max = floor;
                        };
                        if (item.children && item.children.length != 0) {
                            deepEach(item.children, floor + 1);
                        };
                    });
                };
                deepEach(treeData, 1);
                return max;
            },
            /**
              * 表格单元格合并-----行
              * @param {Object} value      当前单元格的值
              * @param {Object} data       当前表格所有数据
              * @param {Object} index      当前单元格的值所在 行 索引
              * @param {Object} property   当前列的property
              * @returns {number}          待合并单元格数量
              */
            mergeRows(value, data, index, property) {
                // 判断 当前行的该列数据 与 上一行的该列数据 是否相等
                if (index !== 0 && value === data[index - 1][property]) {
                    // 返回 0 使表格被跨 行 的那个单元格不会渲染
                    return 0;
                };

                // 判断 当前行的该列数据 与 下一行的该列数据 是否相等
                let rowSpan = 1;
                for (let i = index + 1; i < data.length; i++) {
                    if (value !== data[i][property]) {
                        break;
                    };
                    rowSpan++;
                };
                return rowSpan;
            },
            /**
              * 表格单元格合并-----列
              * @param {Object} value      当前单元格的值
              * @param {Object} row        当前行数据
              * @param {Object} property   当前列的property
              * @param {Object} floorNum   二级指标的层级数
              * @returns {number}          待合并单元格数量
              */
            mergeCells(value, row, property, floorNum) {
                // 取出当前 property 的尾数的 数字值
                let index = Number(property.substring(5));
                // 判断 当前行的该列数据 与 上一列数据 是否相等 (由于 “一级指标” 列不参与跨列,“二级指标” 列开始参与跨列,所以判断 property !== 'index2')
                if(property !== 'index2' && value === row['index' + (index - 1)]){
                    // 返回 0 使表格被跨 列 的那个单元格不会渲染
                    return 0;
                }

                // 判断当前行的该列数据 与 下一列数据 是否相等
                let colSpan = 1;
                for(let i = index; i < floorNum; i++){
                    if(value !== row['index' + (index + 1)]){
                        break;
                    }
                    colSpan++;
                }
                return colSpan;
            },
            /**
             * 权限切换事件
             * @param {Object} item
             */
            changeShowStatus(item) {
                item.checked = !item.checked;
            }
        }
    }
</script>

相关文章

网友评论

      本文标题:ElementUI 树转表格-----跨行跨列(二)

      本文链接:https://www.haomeiwen.com/subject/rifgtltx.html