菜单树结构获取半选中节点

672 阅读1分钟

上周的项目做到了一个需求是给角色分配菜单的时候,需要传给后台半选中状态的数据,可直接通过el-tree的方法设置获取的值是否包含半选中节点getCheckedNodes(false,true),我很想自己试着写一下,如果组件没有提供获取半选中节点的方法的话,我怎么来通过自己写的方法来通过选中节点拿到选中的所有节点(这里指的是选中状态和半选中状态的节点)。

//假设树结构是这样的
[
    {
        name:"A",
        id:"A",
        parentId:"-1",
        children:[
            {
                name:"1",
                id:"1",
                parentId:"A",
                children:[
                    { name:"a",parentId:"1",id:"a" },
                    { name:"b",parentId:"1",id:"b" }
                
                ]
            },
            {
                name:"2",
                id:"2",
                parentId:"A",
                children:[]
            }
        ]
    }
]
A
--1
----a
----b
--2

1.思路

最终效果:我通过拿到的id a,b,提交给后台希望保存的 A,1,a,b

  • 1.目前后台返回给我parentId了,但我想在每一层对象上都记录到从根节点到目前节点的所有关系,这样我最后提交的时候只需要在当前对象上就可拿到所有节点了,然后set去重一下就ok了
  • 2.我需要一个newparentId记录关系的话,那么我就需要递归这个树,并且我需要一个leave等级,来判断我在递归的时候是需要用parentId+当前id,还是用parent的newparentId+当前id
  • 3.为了处理数据方便 我还是需要有一个对象数组来记录所有对象,这样遍历起来好操作,说通俗一点就是把一个树结构的数据给它踩平了,变成数组对象,可以直接用来遍历使用

2.实现

<template>
    <div class="menuTree">
        <el-dialog title="菜单权限" :visible.sync="menuVis" width="480px" :before-close="handleClose">
            
            <el-button size="mini" type="primary" class="mt20" @click="saveFun">保存</el-button>

            <el-tree
                class="tree_div"
                :style="{ height: scrollerHeight, overflow:'auto' }"
                :data="treeData"
                show-checkbox
                node-key="id"
                ref="tree"
                highlight-current
                :props="defaultProps">
            </el-tree>
        
        </el-dialog>
    </div>
</template>

<script>
import { getMenuTree,addBaseResourceAuthority } from "@/api/baseapi";
export default {
    props:['menuVis','openId'],
    components: {},
    computed: {
        scrollerHeight: function(){
            return (window.innerHeight - 500) + 'px';
        }
    },
    data() {
        return {
            treeData:[],
            defaultProps:{
                children:"children",
                label:"title"
            },
            allArray:[],
        
        };
    },
    mounted() {
        getMenuTree({ roleId: this.openId }).then(res=>{
            if(res.status == 200){
                this.treeData = res.data;
                
                //设置等级
                let nodeleave = 1;
                this.treeToArray(this.treeData,nodeleave);
                let selIdArray = [];
                this.allArray.forEach(item=>{
                    if(item.checked){
                        selIdArray.push(item.id);
                    }
                })
                this.$refs.tree.setCheckedKeys(selIdArray);
            }
        })
    },
    methods: {
        
        treeToArray(tree,nodeleave){
            tree.forEach(item=>{ item.nodeleave = nodeleave; })
            tree.forEach(item => {
                //接受对象, 把所有对象都存起来
                this.allArray.push(item);
                if(item.nodeleave == 1){
                    //1级的时候拼接父对象和当前对象
                    item.newParentIds = item.parentId + ',' + item.id;
                }else{
                    //下层的需要拼接父对象的newParentIds和当前对象
                    item.newParentIds = this.allArray.find(findobj=> findobj.id == item.parentId ).newParentIds + ',' + item.id;
                }
                if(item.children && item.children.length){
                    nodeleave = item.nodeleave + 1;
                    this.treeToArray(item.children,nodeleave);
                }
            });
        },
        
        handleClose(){
            this.$emit('update:menuVis', false);
        },

        saveFun(){
            let selchildrenId = this.$refs.tree.getCheckedKeys();
            if(selchildrenId.length){
                let querystring = "";
                this.allArray.forEach(item=>{
                    selchildrenId.forEach(initem=>{
                        if(initem == item.id){
                            querystring = querystring + item.newParentIds + ",";
                        }
                    })
                })

                querystring = new Set(querystring.substring(0,querystring.length-1).split(','));

                let query = {
                    authorityIds: Array.from(querystring).join(','),
                    roleId:this.openId
                }

                addBaseResourceAuthority(query).then(res=>{
                    if(res.status == 200){
                        this.$message.success('保存成功');
                        this.handleClose();
                    }
                })
            }else{
                this.$message.warning('请勾选节点数据');
            }
        },
    },
};
</script>
<style scoped lang="scss">
.menuTree{
    ::v-deep .el-dialog__body{
        padding-top: 0;
    }
    .mt20{
        margin: 10px 0 15px;
    }
}
</style>