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

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

作者: Cherry丶小丸子 | 来源:发表于2022-04-01 14:55 被阅读0次
    demo.png
    <div id="app">
        <el-table :data="tableData" border size="mini" :span-method="tableSpanMethod">
            <el-table-column align="center" prop="index1" label="一级指标">
                <template slot-scope="scope">
                    <el-checkbox
                        v-model="scope.row.index1.check"
                        :indeterminate="scope.row.index1.isIndeterminate"
                        @change="checkboxChange($event, scope.row.index1)">
                        {{ scope.row.index1.label }}
                    </el-checkbox>
                </template>
            </el-table-column>
            <el-table-column align="center" prop="index2" label="二级指标">
                <template slot-scope="scope">
                    <el-checkbox
                        v-model="scope.row.index2.check"
                        :indeterminate="scope.row.index2.isIndeterminate"
                        @change="checkboxChange($event, scope.row.index2)">
                        {{ scope.row.index2.label }}
                    </el-checkbox>
                </template>
            </el-table-column>
            <el-table-column align="center" prop="index3" label="三级指标">
                <template slot-scope="scope">
                    <el-checkbox
                        v-model="scope.row.index3.check"
                        :indeterminate="scope.row.index3.isIndeterminate"
                        @change="checkboxChange($event, scope.row.index3)">
                        {{ scope.row.index3.label }}
                    </el-checkbox>
                </template>
            </el-table-column>
            <el-table-column align="center" prop="index4" label="四级指标">
                <template slot-scope="scope">
                    <el-checkbox
                        v-model="scope.row.index4.check"
                        :indeterminate="scope.row.index4.isIndeterminate"
                        @change="checkboxChange($event, scope.row.index4)">
                        {{ scope.row.index4.label }}
                    </el-checkbox>
                </template>
            </el-table-column>
            <el-table-column align="center" prop="index5.label" label="五级指标"></el-table-column>
        </el-table>
    </div>
    
    <script>
        export default {
            data(){
                return {
                    tableData: [],
                    testData: [
                        {
                            id: '1',
                            pId: '0',
                            label: '基础功能',
                            check: false,
                            isIndeterminate: false,
                            children: [
                                {
                                    id: '1-1',
                                    pId: '1',
                                    label: '需求池',
                                    check: false,
                                    isIndeterminate: false,
                                    children: [
                                        {
                                            id: '1-1-1',
                                            pId: '1-1',
                                            label: '排序',
                                            check: false,
                                            isIndeterminate: false,
                                            children: [
                                                {
                                                    id: '1-1-1-1',
                                                    pId: '1-1-1',
                                                    label: '日期排序',
                                                    check: false,
                                                    isIndeterminate: false,
                                                    children: [
                                                        {
                                                            id: '1-1-1-1-1',
                                                            pId: '1-1-1-1',
                                                            label: 'platform',
                                                            children: []
                                                        }
                                                    ]
                                                },{
                                                    id: '1-1-1-2',
                                                    pId: '1-1-1',
                                                    label: '名称排序',
                                                    check: false,
                                                    isIndeterminate: false,
                                                    children: [
                                                        {
                                                            id: '1-1-1-2-1',
                                                            pId: '1-1-1-2',
                                                            label: 'gisquest',
                                                            children: []
                                                        }
                                                    ]
                                                }
                                            ]
                                        },{
                                            id: '1-1-2',
                                            pId: '1-1',
                                            label: '排期',
                                            check: false,
                                            isIndeterminate: false,
                                            children: [
                                                {
                                                    id: '1-1-2-1',
                                                    pId: '1-1-2',
                                                    label: '季度排期',
                                                    check: false,
                                                    isIndeterminate: false,
                                                    children: [
                                                        {
                                                            id: '1-1-2-1-1',
                                                            pId: '1-1-2-1',
                                                            label: 'platform',
                                                            children: []
                                                        }
                                                    ]
                                                }
                                            ]
                                        }
                                    ]
                                },{
                                    id: '1-2',
                                    pId: '1',
                                    label: '专项工作',
                                    check: false,
                                    isIndeterminate: false,
                                    children: [
                                        {
                                            id: '1-2-1',
                                            pId: '1-2',
                                            label: '任务工单',
                                            check: false,
                                            isIndeterminate: false,
                                            children: [
                                                {
                                                    id: '1-2-1-1',
                                                    pId: '1-2-1',
                                                    label: '知识沉淀',
                                                    check: false,
                                                    isIndeterminate: false,
                                                    children: [
                                                        {
                                                            id: '1-2-1-1-1',
                                                            pId: '1-2-1-1',
                                                            label: 'gisquest',
                                                            children: []
                                                        }
                                                    ]
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ]
                        }
                    ],
                }
            }
        },
        mounted() {
            this.treeToTableData();
        },
        methods: {
            treeToTableData(){
                let ewArr = this.parseTreeToRow(this.testData);
                let tableData = [];
                ewArr.map(item => {
                    let obj = {};
                    item.map((itemc, indexb) => {
                        obj['index' + (indexb + 1)] = {
                            id: itemc.id,
                            pId: itemc.pId,
                            label: itemc.label,
                            check: itemc.check,
                            isIndeterminate: itemc.isIndeterminate,
                        };
                    })
                    tableData.push(obj)
                })
                this.tableData = tableData;
            },
            /**
             * 递归-----将树结构数据格式,转化为,二维数组 表格形式
             * @param node 树的源数据
             * @param data 树转化为二维数组的数据
             * @param row 临时存储数据
             * @returns {*[]}
             */
            parseTreeToRow(node, data = [], row = []) {
                node.map(item => {
                    let obj = {
                        id: item.id,
                        pId: item.pId,
                        label: item.label,
                        check: item.check,
                        isIndeterminate: item.isIndeterminate,
                    }
                    if(item.children && item.children.length != 0){
                        this.parseTreeToRow(item.children, data, [...row, obj]);
                    }else{
                        data.push([...row, obj])
                    }
                })
                return data;
            },
            /**
             * 合并行或列的计算方法
             */
            tableSpanMethod({row, column, rowIndex, columnIndex}){
                return {
                    rowspan: columnIndex < 4 ? this.mergeRows(row[column.property], this.tableData, rowIndex, column.property) : 1,
                    colspan: 1
                };
            },
            /**
             * 表格单元格合并-----行
             * @param {Object} value      当前单元格的值
             * @param {Object} data       当前表格所有数据
             * @param {Object} index      当前单元格的值所在 行 索引
             * @param {Object} property   当前列的property
             * @returns {number}          待合并单元格数量
             */
            mergeRows(value, data, index, property) {
                // 判断 当前行的该列数据 与 上一行的该列数据 是否相等
                if (index !== 0 && value.label === data[index - 1][property].label) {
                    // 返回 0 使表格被跨 行 的那个单元格不会渲染
                    return 0;
                };
    
                // 判断 当前行的该列数据 与 下一行的该列数据 是否相等
                let rowSpan = 1;
                for (let i = index + 1; i < data.length; i++) {
                    if (value.label !== data[i][property].label) {
                        break;
                    };
                    rowSpan++;
                };
                return rowSpan;
            },
            /**
             * checkbox 切换事件
             * @param val 切换后的值
             * @param cell 当前单元格的值
             */
            checkboxChange(val, cell){
                // 根据 id pid 获取到的节点
                let getNode = this.queryNodeById(this.testData, cell.id, cell.pId);
    
                // 当前节点 和 当前节点的所有父级节点集合
                let currentNode = getNode.cNode, parentNode = getNode.pNodes;
    
                // 递归当前节点以及所有子节点 设置全部选中与否
                this.setTreeRecursion(currentNode, val);
    
                // 递归每个父节点的全部子节点个数,以及每个父节点的全部选中的子节点个数
                parentNode.map(item => {
                    let num = this.queryNodesTotal(item.children);
                    let childrenNum = num.total;
                    let childrenCheckNum = num.checkTotal;
    
                    // 设置 父节点的选中 与 isIndeterminate
                    item.check = childrenNum == childrenCheckNum;
                    item.isIndeterminate = childrenCheckNum > 0 && childrenCheckNum < childrenNum;
    
                })
                // 重新构造表格数据
                this.treeToTableData();
            },
            /**
             * 递归-----根据 id 查询当前节点 和 根据 pId 查询 当前节点的所有父级节点集合
             * @param node      树的源数据
             * @param nodeId    节点的 id
             * @param nodePid   节点的 pId
             * @param temp      返回的匹配的节点数据集合
             * @returns {{pNodes: *[], cNode: {}}} pNodes: 父级节点集合,cNode:当前节点
             */
            queryNodeById(node, nodeId, nodePid, temp = { cNode: {}, pNodes: [] }){
                let forFn = (arr, id, pId) => {
                    for (let i = 0; i < arr.length; i++) {
    
                        if (arr[i].id === id) {
                            temp.cNode = arr[i];
                            break;
                        }else if (arr[i].id === pId) {
                            temp.pNodes.push(arr[i]);
                            forFn(node, id, arr[i].pId);
                            break;
                        } else {
                            if (arr[i].children) {
                                forFn(arr[i].children, id, pId)
                            }
                        }
    
                    }
                }
                forFn(node, nodeId, nodePid);
                return temp;
            },
            /**
             * 递归-----树组件节点属性修改
             * @param data 树的源数据
             * @param val 修改属性的值
             * @returns {*} 属性修改后的树的数据
             */
            setTreeRecursion(data, val) {
                if(data.check != undefined && data.check != null){
                    data.check = val; // 切换当前 checkbox 选中状态
                    data.isIndeterminate = false; // 切换当前 checkbox 时,要取消 isIndeterminate
                }
                if(data.children){
                    data.children.map((item, index) => {
                        this.setTreeRecursion(item, val);
                    });
                }
                return data;
            },
            /**
             * 递归-----查询 树组件 共有多少节点
             * @param data  data树的源数据
             * @param num num 总节点数
             * @returns {{checkTotal: number, total: number}} checkTotal: 选中的节点总数,total: 所有节点总数
             */
            queryNodesTotal(data, num = { total: 0, checkTotal: 0 }){
                let forFn = nodes => {
                    for(let i = 0; i < nodes.length; i++){
                        if(nodes[i].check != undefined && nodes[i].check != null){
                            num.total++;
                            if(nodes[i].check) num.checkTotal++;
                        }
    
                        if(nodes[i].children && nodes[i].children.length != 0){
                            forFn(nodes[i].children);
                        }
                    }
                }
                forFn(data);
                return num;
            }
        }
    </script>
    

    相关文章

      网友评论

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

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