基于element ui 树形表格,实现对树形表格的增、删功能。

效果图:代码:

<template>
    <div>
        <!-- default-expand-all	是否默认展开所有行,当 Table 包含展开行存在或者为树形表格时有效 -->
        <el-table :data="tableData" style="width: 100%;font-size:18px" row-key="id" border ref="tableData"
            default-expand-all :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
            :header-cell-style="{ background: '#d6e5fb', padding: '8px 0px' }" :cell-style="{ padding: '4px 0px' }">
            <el-table-column prop="catalog" label="目录" width="230" align="left" header-align="center"
                class-name="hide-overflow">
                <template slot-scope="scope">
                    <el-tooltip class="item" effect="dark" :content="scope.row.catalog + '级'" placement="top">
                        <span class="catalogStyle"> {{ scope.row.catalog + '级' }} </span>
                    </el-tooltip>
                </template>
            </el-table-column>
            <el-table-column prop="task" label="标题" min-width="180" align="center" header-align="center">
                <template slot-scope="scope">
                    <el-input placeholder="请输入内容" v-model="scope.row.task" clearable>
                    </el-input>
                </template>
            </el-table-column>
            <el-table-column label="操作" width="300" align="center" header-align="center">
                <template slot-scope="scope">
                    <el-button @click="addtable(scope)" type="primary" size="small" plain
                        :disabled="scope.row.grade >= CatalogLevel - 1">增加子级</el-button>
                    <el-button @click="addtablefy(scope)" type="primary" size="small" plain>增加同级</el-button>
                    <el-button @click="removetable(scope)" type="primary" size="small" plain
                        :disabled="tableData.length == 1 && scope.row.parentid == 0">删除</el-button>
                </template>
            </el-table-column>
        </el-table>
       <div class="operate">
        <el-button @click="submit" type="primary" size="small" plain>打印</el-button>
       </div>
    </div>
</template>

<script>
export default {
    data() {
        return {
            tableData: [
                {
                    id: 1,
                    task: '',
                    parentid: 0,//一级目录父id为0
                    catalog: "1", //用于记录当前目录
                    grade: 0 //用于记录每个节点在第几级,0表示一级
                },
            ],
            id: 1000,//用于自动生成tabeData的id,确保其唯一,每添加一个同级或子级都进行+1操作
            CatalogLevel: 10, //可随意修改能够的生成目录等级
        }
    },
    methods: {
        //增加子级
        addtable(scope) {
            // 获取其孩子的数量,没有孩子,新增子级值为一,否则加一
            let newChildrenNum = 1
            if (scope.row.children) {
                newChildrenNum = scope.row.children.length + 1
            }
            this.id++ //生成子id的id号
            let arr = [];
            let obj = {
                id: this.id,
                parentid: scope.row.id,
                grade: scope.row.grade + 1,
                task: '',
                // 子级目录编号 = 父级目录编号 + 添加孩子之后的数量
                catalog: scope.row.catalog + '.' + newChildrenNum,
            };
            if (scope.row.children && scope.row.children.length != 0) {
                arr = scope.row.children;
                arr.push(obj);
                this.$set(scope.row, "children", arr);
            } else {
                this.$set(scope.row, "children", [obj]);
            }
        },
        // 将目录字符串转为数组,修改某一位置的值,这个位置由local+grade所决定(这也是根据规律得出的结论),local==grade,这样写便于理解。
        // num表示这个位置要修改的值
        changeChildrenArr(arr, num, local, grade) {
            for (let i = 0; i < arr.length; i++) {
                let listArr = arr[i].catalog.split('')
                listArr[local + grade] = num
                arr[i].catalog = listArr.join('')
                if (arr[i].children && arr[i].children.length > 0) {
                    this.changeChildrenArr(arr[i].children, num, local, grade)
                }
            }
        },
        // 递归寻找其父级,实现添加操作
        addt(arr, parentid, id, list, grade) {
            for (let i = 0; i < arr.length; i++) {
                if (arr[i].id === parentid) {
                    let Arr = arr[i].children
                    let index = Arr.findIndex(obj => obj.id === id)
                    let objj = {
                        id: this.id,
                        parentid: parentid,
                        grade: grade,
                        task: '',
                        catalog: arr[i].catalog + '.' + (index + 2),
                    };
                    // 用于修改同级添加后子目录的变化
                    for (let j = index + 1; j < arr[i].children.length; j++) {
                        let listArr = arr[i].children[j].catalog.split('')
                        listArr[listArr.length - 1] = +listArr[listArr.length - 1] + 1
                        arr[i].children[j].catalog = listArr.join('')
                         // 如果后续的节点还有孩子,还需要递归的修改
                        if (arr[i].children[j].children && arr[i].children[j].children.length > 0) {
                            this.changeChildrenArr(arr[i].children[j].children, listArr[listArr.length - 1], arr[i].children[j].grade, grade)
                            // console.log(arr[i].children[j].children, listArr[listArr.length - 1], arr[i].children[j].grade);
                        }
                    }
                    Arr.splice(index + 1, 0, objj)
                    this.$set(arr[i], "children", Arr);
                } else {
                    if (arr[i].children && arr[i].children != 0) {
                        this.addt(arr[i].children, parentid, id, list, grade)
                    }
                }
            }
        },
        // 用于递归修改一级目录下的节点目录
        changeAfterArr(arr, catalog) {
            for (let i = 0; i < arr.length; i++) {
                if (arr[i].catalog === '') return
                let listArr = arr[i].catalog.split('')
                listArr[0] = catalog
                arr[i].catalog = listArr.join('')
                if (arr[i].children && arr[i].children.length != 0) {
                    this.changeAfterArr(arr[i].children, catalog)
                }
            }
        },
        addtablefy(scope) {
            this.id++
             //增加同级-- 这里要注意是否为第一级
            if (scope.row.parentid) {
                this.addt(this.tableData, scope.row.parentid, scope.row.id, scope.row.list, scope.row.grade)
            } else {
                let index = this.tableData.findIndex(obj => obj.id === scope.row.id)
                let objj = {
                    id: this.id,
                    parentid: 0,
                    grade: scope.row.grade,
                    task: '',
                    catalog: (index + 2) + '',
                };
                // 遍历同一父级下新增节点之后的节点,修改其目录值
                for (let j = index + 1; j < this.tableData.length; j++) {
                    this.tableData[j].catalog = +this.tableData[j].catalog + 1
                    if (this.tableData[j].children && this.tableData[j].children.length > 0) {
                        this.changeAfterArr(this.tableData[j].children, this.tableData[j].catalog)
                    }
                }
                this.tableData.splice(index + 1, 0, objj)
            }
        },
        //  递归寻找其父级,实现删除操作
        eggt(arr, parentid, id) {
            for (let i = 0; i < arr.length; i++) {
                if (arr[i].id === parentid) {
                    let Arr = arr[i].children
                    let index = Arr.findIndex(obj => obj.id === id)

                    // 遍历使同一父级下所删除孩子节点之后的节点,修改其目录值
                    for (let j = index + 1; j < arr[i].children.length; j++) {
                        let listArr = arr[i].children[j].catalog.split('')
                        listArr[listArr.length - 1] = +listArr[listArr.length - 1] - 1
                        arr[i].children[j].catalog = listArr.join('')
                        // 如果后续的节点还有孩子,还需要递归的修改
                        if (arr[i].children[j].children && arr[i].children[j].children.length > 0) {
                            this.changeChildrenArr(arr[i].children[j].children, listArr[listArr.length - 1], arr[i].children[j].grade, arr[i].children[j].grade)
                        }
                    }
                    Arr.splice(index, 1)
                    this.$set(arr[i], "children", Arr)
                } else {
                    if (arr[i].children && arr[i].children != 0) {
                        this.eggt(arr[i].children, parentid, id)
                    }
                }
            }
        },
        // 删除操作
        removetable(scope) {
            this.$confirm("是否删除", "提示", {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                type: "warning",
                dangerouslyUseHTMLString: true,
            })
                .then(() => {
                    // 判断其是否为一级目录
                    if (scope.row.parentid != 0) {
                        this.eggt(this.tableData, scope.row.parentid, scope.row.id)
                    } else {
                        let index = this.tableData.findIndex(obj => obj.id === scope.row.id)
                        // 遍历使同一父级下新增孩子位置之后的孩子目录值加1
                        for (let j = index + 1; j < this.tableData.length; j++) {
                            this.tableData[j].catalog = +this.tableData[j].catalog - 1
                            console.log(this.tableData[j].catalog, this.tableData[j].children);
                            if (this.tableData[j].children && this.tableData[j].children.length > 0) {
                                this.changeAfterArr(this.tableData[j].children, this.tableData[j].catalog)
                            }
                        }
                        this.tableData.splice(index, 1)
                    }
                })
                .catch(() => {
                });
        },
        // 打印
        submit() {
            console.log(Array.from(this.tableData));
        }

    }
}
</script> 
<style scoped>
.item {
    margin: 4px;
}
.operate{
    display: flex;
    justify-content: end;
    width: 100%;
    min-width: 100px;
    padding-top: 50px;
    padding-right: 30px;
    box-sizing: border-box;
}
</style>
<style>
.hide-overflow .cell {
    overflow: hidden !important;
    white-space: nowrap !important;
}
</style>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值