美文网首页vue2前端开发那些事儿
【vue+elementui】el-table树形结构

【vue+elementui】el-table树形结构

作者: IrisLong | 来源:发表于2021-02-19 16:24 被阅读0次

    需求:

    1. 带复选框的树形table结构
    2. 勾选了子级,父级也会勾选;勾选父级,父级内部所有子级/孙子级都会被勾选
    3. 取消同理

    核心代码:

    • 树形table结构
    <el-table
        :data="tableData.list"
        @selection-change="selectChange"
        border
        stripe
        size="mini"
            header-cell-class-name="tableHeader"
        row-key="id"
        :tree-props="{ children: 'children' }"
        :default-expand-all="true"
        @select="handleSelect"
        @select-all="handleSelectAll"
        ref="multipleTable"
    >
            <el-table-column type="selection"></el-table-column>
        <el-table-column prop="code" label="编码" width="160"> </el-table-column>
        <el-table-column prop="name" label="名称" width="120"> </el-table-column>
        <el-table-column label="操作" width="130">
                <template slot-scope="scope">
                    <el-button small="small" type="text" @click="editOne('add', scope.row)">新增</el-button>
                <el-button small="small" type="text" @click="editOne('edit', scope.row)">编辑</el-button>
                <el-button
                        v-if="!scope.row.children"
                    small="small"
                    type="text"
                    @click="deleteOne('one', scope.row)"
                    >删除</el-button
                 >
             </template>
            </el-table-column>
    </el-table>
    
    • 勾选逻辑
            handleSelectAll() {
                const isAllSelected = this.$refs.multipleTable.store.states.isAllSelected
                let _handleSelectAll = data => {
                    data.forEach(item => {
                        this.$refs.multipleTable.toggleRowSelection(item, isAllSelected)
                        _handleSelectAll(item.children || [])
                    })
                }
                _handleSelectAll(this.tableData.list)
            },
            handleSelect(selection, current) {
                // 判断selection中是否存在current,若是存在那么就代表是被勾选上了,若是不存在代表是取消勾选了
                const isChecked = !!selection.find(item => item.id === current.id)
                // 如果当前项被取消勾选
                if (!isChecked) {
                    // 那么其所有的祖先也应该被取消勾选
                    this.uncheckedParents(selection, current)
                    // 那么其所有的后代也应该被取消勾选
                    this.toggleCheckedChildrens(selection, current, false)
                } else {
                    // 如果当前项被勾选
                    // 那么若同一组的元素都被勾选了,那么父元素将也被勾选,依次往上类推
                    this.checkedParents(selection)
                    // 那么其所有的后代都要被勾选
                    this.toggleCheckedChildrens(selection, current, true)
                }
            },
            uncheckedParents(selection, item) {
                let _uncheckedParents = data => {
                    return data.find(element => {
                        if (element.id === item.id) {
                            return true
                        } else if (_uncheckedParents(element.children || [])) {
                            this.$refs.multipleTable.toggleRowSelection(element, false)
                            for (let i = selection.length - 1; i >= 0; i--) {
                                if (selection[i].id === element.id) {
                                    selection.splice(i, 1)
                                    break
                                }
                            }
                            return true
                        } else {
                            return false
                        }
                    })
                }
                _uncheckedParents(this.tableData.list)
            },
            toggleCheckedChildrens(selection, item, isChecked) {
                let _toggleCheckedChildrens = data => {
                    data.find(element => {
                        this.$refs.multipleTable.toggleRowSelection(element, isChecked)
                        if (isChecked && !selection.find(item => item.id === element.id)) {
                            selection.push(element)
                        } else if (!isChecked && selection.find(item => item.id === element.id)) {
                            for (let i = selection.length - 1; i >= 0; i--) {
                                if (selection[i].id === element.id) {
                                    selection.splice(i, 1)
                                    break
                                }
                            }
                        }
                        _toggleCheckedChildrens(element.children || [])
                    })
                }
                _toggleCheckedChildrens(item.children || [])
            },
            checkedParents(selection) {
                let _checkedParents = element => {
                    const children = element.children
                    if (children && children.length) {
                        const allChildrenChecked = children.every(child => {
                            return _checkedParents(child)
                        })
                        if (allChildrenChecked) {
                            this.$refs.multipleTable.toggleRowSelection(element, true)
                            if (!selection.find(item => item.id === element.id)) {
                                selection.push(element)
                            }
                        }
                    }
                    return selection.find(item => item.id === element.id)
                }
                this.tableData.list.forEach(element => {
                    _checkedParents(element)
                })
            },
    

    相关文章

      网友评论

        本文标题:【vue+elementui】el-table树形结构

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