element-ui table tree 级联选择

孟泽宇
2023-12-01

示例页面地址

<!DOCTYPE html>
<html lang="zh-Hans">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Element-UI 树表格级联选择</title>
    <link rel="stylesheet" href="https://unpkg.com/element-ui@2.15.9/lib/theme-chalk/index.css">
</head>

<body>
    <div id="app">
        <el-table border ref="multipleTable" 
            :data="list" tooltip-effect="dark" style="width: 100%"
            @selection-change="handleSelectionChange" 
            row-key="id" default-expand-all
            :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" 
            @select="handleSelect"
            @select-all="handleSelectAll">
            <el-table-column align="center" type="selection" width="55"></el-table-column>
            <el-table-column label="日期" width="160">
                <template slot-scope="scope">{{ scope.row.date }}</template>
            </el-table-column>
            <el-table-column prop="name" label="姓名" width="120">
            </el-table-column>
            <el-table-column prop="address" label="地址" show-overflow-tooltip>
            </el-table-column>
        </el-table>
    </div>
    <script src="https://unpkg.com/vue@2"></script>
    <script src="https://unpkg.com/element-ui"></script>
    <script>
        Vue.use(ELEMENT)
        
        function treeToList(list, children, out = []) {
            list.forEach(item => {
                out.push(item);
                if (item[children]?.length) {
                    treeToList(item[children], children, out)
                }
            })
            return out;
        }

        new Vue({
            el: '#app',
            data() {
                return {
                    list: [],
                    multipleSelection: [],

                    // 配置
                    setting:{
                        childrenKey:'children',
                        idKey:'id',
                        pidKey:'pid',
                        listPropName:'list',
                        tableRef:'multipleTable'
                    }
                }
            },
            computed: {
                allRows() {
                    return treeToList(this[this.setting.listPropName],this.setting.childrenKey)
                },
            },
            mounted(){
                queryData().then(list=>this.list = list);
            },
            methods: {
                /**选中状态改变 */
                handleSelectionChange(val) {
                    this.multipleSelection = val;
                },
                /**单行选中 */
                handleSelect(selection, row) {
                    let checked = selection.includes(row);
                    if (checked) {
                        this.selectedParents(selection,row);
                        this.toggleRowSelections(row.children, true)
                    } else {
                        this.unSelectedParents(row)
                        this.toggleRowSelections(row.children, false)
                    }
                },

                /**检查并选中父级节点 */
                selectedParents(selection,row) {
                    let parent = this.getParentRow(row)
                    if (!parent) { return }

                    // 所有有兄弟节点均已被选中
                    if (!parent.children.find(item => !selection.includes(item))) {
                        // 选中当前节点
                        this.toggleRowSelection(parent, true)
                        // 并继续向上检索
                        this.selectedParents(selection,parent);
                    }
                },

                /**行取消选中后 */
                unSelectedParents(row) {
                    let parent = this.getParentRow(row);
                    while (parent) {
                        this.toggleRowSelection(parent, false)
                        parent = this.getParentRow(parent);
                    }
                },

                getParentRow(row) {
                    return this.allRows.find(item => item.id === row.pid)
                },

                /** 设置树形列表选中状态 */
                toggleRowSelections(list, checked) {
                    list?.forEach(item => {
                        this.toggleRowSelection(item, checked)
                        if (item[this.setting.childrenKey]?.length) {
                            this.toggleRowSelections(item[this.setting.childrenKey], checked);
                        }
                    })
                },

                toggleRowSelection(row, checked) {
                    this.$refs[this.setting.tableRef].toggleRowSelection(row, checked)
                },


                /**全选 */
                handleSelectAll(selection) {
                    let noroots = this.allRows.length - this.list.length;
                    let selnoroots = selection.filter(item => item[this.setting.pidKey] !== 0).length;
                    let selroots = selection.filter(item => item[this.setting.pidKey] === 0).length;
                    if ((selroots === 0)) {
                        if (noroots === selnoroots) {
                            this.toggleRowSelections(this.list, false);
                            return;
                        }
                    }
                    this.toggleRowSelections(this.list, true);
                },
            }
        })



        function queryData() {
            return Promise.resolve([
                {
                    id: 1, pid: 0, date: "2016-05-02", name: "wangxiaohu",
                    children: [
                        { id: 11, pid: 1, date: "2016-05-04", name: "wangxiaohu" },
                        { id: 12, pid: 1, date: "2016-05-04", name: "wangxiaohu" },
                        { id: 13, pid: 1, date: "2016-05-04", name: "wangxiaohu" },
                    ]
                },
                { id: 2, pid: 0, date: "2016-05-04", name: "wangxiaohu" },
                { id: 3, pid: 0, date: "2016-05-04", name: "wangxiaohu" },
                { id: 4, pid: 0, date: "2016-05-04", name: "wangxiaohu" },
                { id: 5, pid: 0, date: "2016-05-04", name: "wangxiaohu" },
            ])
        }
    </script>
</body>

</html>
 类似资料: