element ui --el-select 嵌套el-tree多选联动、删除联动

需求:

el-select 下拉框嵌套el-tree 树形组件 完成多选、删除、搜索、清空选项等联动功能。

特殊需求:(当子节点全部选中时el-select中只展示父节点tag,el-tree组件父子节点全部选中,当el-select中父节点tag删除时,el-tree中父子节点的选中状态全部清除)

代码实现:

页面部分:

<el-form-item label="适用范围:" prop="selectList" :rules="[{required:true,message: '适用范围不能为空'}]">
                        <el-select  
                            class="el-input-search" 
                            v-model="ruleForm.selectList"  
                            ref="orgtxSelect"
                            :multiple="true"
                            @remove-tag="removetag" 
                            @clear="clearall" 
                            clearable 
                            @change ="$forceUpdate();"
                            style="width:300px" >
                            <el-option 
                                disabled 
                                value="" 
                                style="height:auto;background-color: #fff;" 
                                class="noDisabledCursor">
                                <el-input 
                                    :validate-event="false" 
                                    v-model="filterText" 
                                    placeholder="请输入" 
                                    @click.stop.native
                                    style="margin-bottom:8px;"></el-input>
                                <el-tree
                                    :data="orgList"
                                    show-checkbox
                                    default-expand-all
                                    highlight-current
                                    :expand-on-click-node="false"
                                    :check-on-click-node="true"
                                    :props="defaultProps"
                                    node-key="id"
                                    @check="handleNodeCheck"
                                    @node-click="handleNodeClick"
                                    :filter-node-method="filterNode"
                                    class="dialogTree"
                                    ref="orgtxtree"
                                ></el-tree>
                            </el-option>
                        </el-select>
                    </el-form-item>

methods代码实现:

//点击树形元素或者复选框时方法实现
handleNodeClick(data,node){
            this.selectTree= [];
            this.ruleForm.selectList = [];
            let datalist = this.$refs.orgtxtree.getCheckedNodes();
            let keyArrList =  this.$refs.orgtxtree.getCheckedKeys();
            for(let i = 0;i < datalist.length;i++){
                if(datalist[i].level == 1){
                    this.selectTree.push({id:datalist[i].id,label:datalist[i].nodeName})
                    this.ruleForm.selectList.push(datalist[i].nodeName);
                    break;
                }else{
                    if(keyArrList.indexOf(Number(datalist[i].parentId)) == -1){
                        this.selectTree.push({id:datalist[i].id,label:datalist[i].nodeName})
                        this.ruleForm.selectList.push(datalist[i].nodeName);
                    }
                }
            }
        },
        handleNodeCheck(data,node){
            this.selectTree= [];
            this.ruleForm.selectList = [];
            for(let i =0;i< node.checkedNodes.length;i++){
                console.log(node.checkedNodes[i])
                if(node.checkedNodes[i].level == 1){
                    this.selectTree.push({id:node.checkedNodes[i].id,label:node.checkedNodes[i].nodeName})
                    this.ruleForm.selectList.push(node.checkedNodes[i].nodeName);
                    break;
                }else{
                    if(node.checkedKeys.indexOf(Number(node.checkedNodes[i].parentId)) == -1){
                        this.selectTree.push({id:node.checkedNodes[i].id,label:node.checkedNodes[i].nodeName})
                        this.ruleForm.selectList.push(node.checkedNodes[i].nodeName);
                    }
                }
            }
        },
//点击select中删除按钮方法实现
 
removetag(val){
            let checkNodes = this.$refs.orgtxtree.getCheckedNodes();  
            let keyArrList =  this.$refs.orgtxtree.getCheckedKeys();
            let selectList = this.selectTree.map(x=>x.label);
            for(let i = 0; i < checkNodes.length; i++){
                if(checkNodes[i].nodeName == val){
                    if(checkNodes[i].childrenList.length > 0){
                        keyArrList.splice(i,1);
                        this.selectTree.splice(selectList.indexOf(val),1);
                        this.del(checkNodes[i].childrenList,keyArrList);
                    }else{
                        checkNodes.splice(i, 1);
                        this.selectTree.splice(selectList.indexOf(val),1);
                        this.$refs.orgtxtree.setCheckedNodes(checkNodes);
                    }
                    break;
                }
            }
        },
        // 递归删除树组件选中状态
        del(arr,dataList) {
            for (let item of arr) {
                if(item.childrenList.length > 0 ) {
                    this.del(item.childrenList);
                }else{
                    dataList.splice(dataList.indexOf(Number(item.id)),1)
                }
            }
            this.$nextTick(() => {
                this.$refs.orgtxtree.setCheckedKeys(dataList)
            })
        },
        clearall(){
            this.selectTree = []
            this.$nextTick(() => {
                this.$refs.orgtxtree.setCheckedNodes([])
            })
        },

输入框搜索代码实现(watch监听filterText):

 watch:{
        infoData:{
            handler(val){
                this.ruleForm = val;
                this.$set(this.ruleForm,'selectList',this.ruleForm.nodeNameList)
          this.$refs.orgtxtree.setCheckedKeys(this.ruleForm.checkList);
this.$nextTick(()=>{
                if(this.$refs.ruleForm){
                            let checkedList = this.$refs.orgtxtree.getCheckedNodes();
                            let keyArrList = this.ruleForm.checkList;
                            this.selectTree = [];
                            for(let i = 0;i < checkedList.length;i++){
                                if(checkedList[i].level == 1){
                                    this.selectTree.push({id:checkedList[i].id,label:checkedList[i].nodeName})
                                    break;
                                }else{
                                    if(keyArrList.indexOf(Number(checkedList[i].parentId)) == -1){
                                        this.selectTree.push({id:checkedList[i].id,label:checkedList[i].nodeName})
                                    }
                                }
                            }
                        }

                    });
                this.$nextTick(()=>{
                    this.$refs.ruleForm.clearValidate();//清空表单
                })
            }
        },
        // 监听输入值
        filterText(val) {
            this.$refs.orgtxtree.filter(val);
        }
    },

在mathods中过滤输入搜索值:

filterNode(value, data) {
            if (!value) return true;
            return data.nodeName.indexOf(value) !== -1;
        },

 

数据结构:

 orgList:[
                {
                    id:11,
                    leavel:1,
                    nodeId:'k01',   
                    nodeName:'这是第一级',
                    parentId:'',
                    childrenList:[{
                        id:101,
                        leavel:2,
                        nodeId:'k0101',   
                        nodeName:'这是第二级',
                        parentId:'11',
                        childrenList:[{
                            id:10101,
                            leavel:3,
                            nodeId:'k010101',   
                            nodeName:'这是第三级',
                            parentId:'101',
                            childrenList:[]
                        }]
                    },{
                        id:201,
                        leavel:2,
                        nodeId:'k0102',   
                        nodeName:'这是第二级',
                        parentId:'11',
                        childrenList:[{
                            id:10102,
                            leavel:3,
                            nodeId:'k010102',   
                            nodeName:'这是第三级',
                            parentId:'201',
                            childrenList:[]
                        }]
                    }]
                }
            ]

实现效果图:

 最后:提交给接口入参 直接用 (this.selectTree.map(x=>x.id).filter(k=>k!= null)).join(',') 获取当前选中父节点或半选中子节点所组成的id 并转换成字符串

posted @ 2023-01-04 16:25  巫小婆  阅读(3504)  评论(2编辑  收藏  举报