当前位置: 首页 > 知识库问答 >
问题:

前端 - elementUI el-table子节点选中后没有打勾?

甄飞飙
2023-06-18

image.png
第一层是父节点,点击下面的子节点,子节点已经被选中了,但是没有选中打勾的效果
全选所有、选择父级都可以,但是只要父级下面有多个子节点,选择其中一个子节点的时候就不行,如果只有一个子节点也是可以的

 <el-table
                    v-loading="loading"
                    :data="customList"
                    @selection-change="handleSelectionChange"
                    :row-key='rowKeyFunc'
                    :tree-props="{children: 'children'}"
                    :row-class-name="rowClassNameFun"
                    ref="table"
                    @select-all="selectAllFun"
                    @select="selectFun"
            >
                <el-table-column type="selection" width="55" align="center"/>
                <el-table-column label="买家名称" align="center" prop="customName" width="120px"/>
                <el-table-column
                        label="联系人"
                        align="center"
                        prop="linkman"
                        width="180"
                >
                </el-table-column>
                <el-table-column
                        label="联系电话"
                        align="center"
                        width="200"
                        prop="phone"
                />
                <el-table-column
                        label="地址"
                        align="center"
                        width="200"
                        prop="address"
                />
            </el-table>
isFun: false,
                oneProductIsSelect: [],
                // 遮罩层
                loading: true,
                // 选中数组
                ids: [],
                // 非单个禁用
                single: true,
                // 非多个禁用
                multiple: true,
                // 当前编辑数据
                current: null,
                // 是否显示编辑弹窗
                showEdit: false,
                //买家添加弹框
                showCustomAdd: false,
                // 是否显示导入弹窗
                showImport: false,
                // 搜索表单是否展开
                searchExpand: false,
                statisticsNum: [],
                count: 0,
                isSelectAll: false,//全选标识
                selectIds: [],//全选ids
                // 操作类型
                type: null,
                customList: [],
// 查询列表
            async getList() {
                this.loading = true;
                const res = await getCustomList({});
                this.customList = this.$util.toTreeData({
                    data: res,
                    idField: "idStr",
                    parentIdField: "parentStr",
                });
                //这一步是为了将父和子之间有联系,给子定义一个taskId,将子的taskId和父的id一致
                this.customList.forEach((item, index) => {
                    if (item.children) {
                        item.children.forEach((cItem, cIndex) => {
                            cItem.taskId = item.linkmanId;
                        });
                    }
                });
                // 由于后端返回的数组id不唯一(父里的id和其中一个子的id一样),然后:row-key='id'里面的id要是唯一值,所以处理了一下,将父的id改变,将数组里面的id都唯一,当然,你可以跟后端商量一下,返回给你一个唯一值,这个处理代码就可以省略了
                this.customList = this.customList.map((item, index) => {
                    return {
                        ...item,
                        uuid: `${index}-${this.guid()}`
                    }
                })
                this.loading = false; // 遮罩层
                this.initData(this.customList)
            },
            initData(data) {
                data.forEach((item) => {
                    item.isSelect = false; //默认为不选中
                    if (item.children && item.children.length) {
                        this.initData(item.children);
                    }
                });
            },
            // 判断是不是全选
            checkIsAllSelect() {
                this.oneProductIsSelect = [];
                this.customList.forEach((item) => {
                    this.oneProductIsSelect.push(item.isSelect);
                });
                //判断一级产品是否是全选.如果一级产品全为true,则设置为取消全选,否则全选
                let isAllSelect = this.oneProductIsSelect.every((selectStatusItem) => {
                    return true == selectStatusItem;
                });
                return isAllSelect;
            },
            // 全选或者全不选(这个是祖父的勾选)
            selectAllFun(selection) {
                let isAllSelect = this.checkIsAllSelect();
                this.customList.forEach((item) => {
                    item.isSelect = isAllSelect;
                    this.$refs.table.toggleRowSelection(item, !isAllSelect);
                    this.selectFun(selection, item);
                });
            },
            selectFun(selection, row) {
                this.setRowIsSelect(row);
            },
            setRowIsSelect(row) {
                console.log(row);
                //当点击父级点复选框时,当前的状态可能为未知状态,所以当前行状态设为false并选中,即可实现子级点全选效果
                if (row.isSelect == "half") {
                    row.isSelect = false;
                    this.$refs.table.toggleRowSelection(row, true);
                }
                row.isSelect = !row.isSelect;
                //判断操作的是子级点复选框还是父级点复选框,如果是父级点,则控制子级点的全选和不全选
                if (row.children && row.children.length > 0) {
                    row.children.forEach((item) => {
                        item.isSelect = row.isSelect;
                        this.$refs.table.toggleRowSelection(item, row.isSelect);
                    });
                } else {
                    //操作的是子节点  1、获取父节点  2、判断子节点选中个数,如果全部选中则父节点设为选中状态,如果都不选中,则为不选中状态,如果部分选择,则设为不明确状态
                    let parentId = row.taskId;
                    // this.customList.forEach((item) => {
                    //     if (item.linkmanId == parentId) {
                    //         item.children.forEach(obj=>{
                    //             if (row.linkmanId == obj.linkmanId) {
                    //                 console.log(obj);
                    //                 this.$refs.table.toggleRowSelection(obj, true);
                    //             }
                    //         })
                    //     }
                    // })
                    this.customList.forEach((item) => {
                        let isAllSelect = [];
                        if (item.linkmanId == parentId) {
                            console.log(item)
                            if (item.children) {
                                item.children.forEach((databaseSourceListItem) => {
                                    isAllSelect.push(databaseSourceListItem.isSelect);
                                });
                            }
                            if (
                                isAllSelect.every((selectItem) => {
                                    return true == selectItem;
                                })
                            ) {
                                item.isSelect = true;
                                this.$refs.table.toggleRowSelection(item, true);
                            } else if (
                                isAllSelect.every((selectItem) => {
                                    return false == selectItem;
                                })
                            ) {
                                item.isSelect = false;
                                this.$refs.table.toggleRowSelection(item, false);
                            } else {
                                item.isSelect = "half";

                            }
                        }
                    });
                }
            },
            rowClassNameFun({row}) {
                if (row.isSelect == 'half') {
                    return "indeterminate";
                }
            },
            //生成唯一ID
            guid() {
                return Number(
                    Math.random().toString().substr(3, 3) + Date.now()
                ).toString(36);
            },
            //row-key唯一值
            rowKeyFunc(row) {
                if (row.uuid) {
                    return row.uuid
                } else {
                    return row.linkmanId
                }
            },
            // 多选框选中数据,这个里面逻辑下面有提到
            handleSelectionChange(selection) {
                if (this.isFun) {
                    this.isFun = false
                    return
                }
                // 判断当前选中的节点是否有子节点
                if (selection.length === 0) {
                    selection = []
                    this.ids = [];
                    this.isFun = true
                    this.multiple = !selection.length
                    return
                }
                this.single = selection.length !== 1;
                this.multiple = !selection.length
                this.ids = selection.map((item) => item.linkmanId);
            },
::v-deep .indeterminate .el-table-column--selection .cell .el-checkbox {
        display: block !important;
    }

    ::v-deep .indeterminate .el-checkbox__input .el-checkbox__inner {
        background-color: #4a97eb !important;
        border-color: #4a97eb !important;
        color: #fff !important;
    }

    ::v-deep .indeterminate .el-checkbox__input.is-checked .el-checkbox__inner::after {
        transform: scale(0.5);
    }

    ::v-deep .indeterminate .el-checkbox__input .el-checkbox__inner::after {
        border-color: #c0c4cc !important;
        background-color: #c0c4cc;
    }

    ::v-deep .indeterminate .el-checkbox__input .el-checkbox__inner::after {
        content: "";
        position: absolute;
        display: block;
        background-color: #fff;
        height: 2px;
        transform: scale(0.5);
        left: 0;
        right: 0;
        top: 5px;
        width: auto !important;
    }

代码是参考这个写的 作者:阿wei程序媛 https://blog.csdn.net/m0_58565372/article/details/130766588

共有2个答案

乐正浩言
2023-06-18

横杠表示的checkbox有中间状态,即选中但未全选
https://element.eleme.cn/#/zh-CN/component/checkbox#indetermi...

靳举
2023-06-18

解决了,elementUI版本问题,"element-ui": "2.15.7" ->"element-ui": "2.15.13",升级到最新版就行了。然后自己补充了一个选中后的方法setSelectItem(),selectItem后来定义的选中后的数据,不包括半选节点

// 全选或者全不选(这个是祖父的勾选)
            selectAllFun(selection) {
                let isAllSelect = this.checkIsAllSelect();
                if(isAllSelect){
                    this.selectItem=[];
                }else{
                    this.customList.forEach((item) => {
                        this.selectItem.push(item);
                        if(item.children?.length>0){
                            item.children.forEach(obj=>{
                                this.selectItem.push(obj);
                            })
                        }
                    })
                }
                this.customList.forEach((item) => {
                    item.isSelect = isAllSelect;
                    this.$refs.table.toggleRowSelection(item, !isAllSelect);
                    this.selectFun(selection, item,true);
                });
            },
            selectFun(selection, row,state) {
                this.setRowIsSelect(row,state);
            },
            setRowIsSelect(row,state) {
                //当点击父级点复选框时,当前的状态可能为未知状态,所以当前行状态设为false并选中,即可实现子级点全选效果
                if (row.isSelect == "half") {
                    row.isSelect = false;
                    this.$refs.table.toggleRowSelection(row, true);
                }
                row.isSelect = !row.isSelect;
                //判断操作的是子级点复选框还是父级点复选框,如果是父级点,则控制子级点的全选和不全选
                if (row.children && row.children.length > 0) {
                    row.children.forEach((item) => {
                        item.isSelect = row.isSelect;
                        this.$refs.table.toggleRowSelection(item, row.isSelect);
                    });
                } else {
                    //操作的是子节点  1、获取父节点  2、判断子节点选中个数,如果全部选中则父节点设为选中状态,如果都不选中,则为不选中状态,如果部分选择,则设为不明确状态
                    let parentId = row.taskId;
                    this.customList.forEach((item) => {
                        let isAllSelect = [];
                        if (item.linkmanId == parentId) {
                            if (item.children) {
                                item.children.forEach((databaseSourceListItem) => {
                                    isAllSelect.push(databaseSourceListItem.isSelect);
                                });
                            }
                            if (
                                isAllSelect.every((selectItem) => {
                                    return true == selectItem;
                                })
                            ) {
                                item.isSelect = true;
                                this.$refs.table.toggleRowSelection(item, true);
                            } else if (
                                isAllSelect.every((selectItem) => {
                                    return false == selectItem;
                                })
                            ) {
                                item.isSelect = false;
                                this.$refs.table.toggleRowSelection(item, false);
                            } else {
                                item.isSelect = "half";
                            }
                        }
                    });
                }
                if(!state) this.setSelectItem(row);
            },
            /* 设置选中集合 */
            setSelectItem(row){
                let index = this.selectItem.indexOf(row);
                if(row.isSelect){
                    // 如果不存在则放入到选中集合中
                    if(!(index>-1)){
                        this.selectItem.push(row);
                        // 如果选的是父级,且子集存在则将子集放入到选中集合
                        if(!row.taskId){//不存在则是父级
                            row.children?.forEach(item=>{
                                const i = this.selectItem.indexOf(item);
                                // 不存在则将子集放入
                                if(!(i>-1)){
                                    this.selectItem.push(item);
                                }
                            })
                        }else{//存在则为子集,需要判断是否该子集的父级下级数据是否全选,全选则需要放入父级
                            this.customList.forEach(item=>{
                                if(item.linkmanId === row.taskId){
                                    // 判断该父级下其它子集是否在集合中
                                    let state = true;
                                    item.children?.forEach(obj=>{
                                        const i = this.selectItem.indexOf(obj);
                                        if(!(i>-1)){//不存在则设置为true
                                            state = false;
                                        }
                                    });
                                    if(state){
                                        this.selectItem.push(item);
                                    }
                                }
                            })
                        }
                    }
                }else{//取消选择
                    // 如果存在则从集合中删除
                    if(index>-1){
                        this.selectItem.splice(index, 1);
                        if(!row.taskId){//父级
                            // 如果是父级则同时删除选择数组中的子集
                            row.children?.forEach(obj=>{
                                const i = this.selectItem.indexOf(obj);
                                if(i>-1){//存在则删除选中的子集
                                    this.selectItem.splice(i, 1);
                                }
                            });
                        }else{//子集
                            // 取消子集,则父级取消
                            this.customList.forEach(item=>{
                                if(item.linkmanId === row.taskId){
                                    const i = this.selectItem.indexOf(item);
                                    if(i>-1){//存在则删除选中子集的父级
                                        this.selectItem.splice(i, 1);
                                    }
                                }
                            })
                        }
                    }
                }
            },
 类似资料: