tree 单选累计 全选累加 取消删除,勾选添加,切换tree节点保留之前选中的累加

image.png

功能描述
1.tree是类加载(数据比较多),点击的时候获取最新的数据
2.右侧全选的有部门 公司 人员(接口返回 前端把人员和部门的数据累加起来)
3.选中的数据显示到最底下(取消。里面的数据对应取消)
4.判断全选的状态
5.单选的时候,判断code是否相等,在判断是否选中,选中就往里面push数据,去掉就删除对象的code的数据
6.全选状态,把累加的数组(最下面的数组和右边checkbox取交集,取出来的数组再和右边checkbox对比)
代码如下

let checkedItemCode=this.checkedNodes.filter(item => this.userCheckAllList[0].userList.some(ele=>ele.detailCode===item.detailCode)); //交集的数组(选中)
                        this.userCheckAllList[0].checkAllUser = checkedItemCode.length===this.userCheckAllList[0].userList.length ||  checkedItemCode.length > this.userCheckAllList[0].userList.length
                        this.userCheckAllList[0].isIndeterminateUser  =checkedItemCode.length>0&&checkedItemCode.length < this.userCheckAllList[0].userList.length

html结构(change事件放到checkbox上面不要放checkbox-group上)

<!--弹窗里面嵌套弹框,需要是在第二个弹窗里面设置:append-to-body="true"-->
                       <el-dialog  :close-on-click-modal="false" :before-close="closeDialogTwo" :title="dialogTitleTwo"
                                   :visible.sync="dialogVisibleTwo" :append-to-body="true">
                           <div  class="dialog">
                               <div class="searchBox">
                                   <span class="textBox"></span>
                                   <span class="searchInput">
                                       <el-input v-model.trim="searchKey" placeholder="请输入关键字查询" @input="handleGroupKey"></el-input>
                                   </span>
                               </div>
                               <div class="dialogWrapper">
                                   <div class="dialogLift">
                                       <!--机构部门-->
                                       <el-tree
                                               accordion
                                               @check-change="handleCheckChange"
                                               @node-click="handleNodeClick"
                                               :render-content="renderContent"
                                               :props="props"
                                               :load="loadNode"
                                               lazy
                                               node-key="deptCode"
                                               ref="tree">
                                       </el-tree>
                                   </div>
                                   <div class="dialogRight">
                                       <!--搜索成员-->
                                       <div v-for="(item,index) in userCheckAllList" :key="index">
                                           <el-checkbox :indeterminate="item.isIndeterminateUser" v-model="item.checkAllUser" @change="handleCheckAllChange">{{item.menuDesc}}</el-checkbox>
                                           <el-checkbox-group
                                                   class="searchListBox"
                                                   v-model="item.checkedNameList"
                                                   ref="checked"
                                           >
                                               <el-checkbox
                                                       @change="handleChangeSearch(value)"
                                                       calss="checkBox"
                                                       v-for="(value,index) in item.userList"
                                                       :label="value.detailCode"
                                                       :key="value.detailCode+index"
                                               >
                                                   <span v-if="value.detailType==1"><i class="iconfont icon-jigouyinhang"></i></span>
                                                   <span v-else-if="value.detailType==2"><i class="iconfont icon-bumen"></i></span>
                                                   <span v-else><i class="iconfont icon-renyuan1"></i></span>
                                                   {{value.detailName}}
                                               </el-checkbox>
                                           </el-checkbox-group>
                                       </div>
                                   </div>
                               </div>
                               <div class="dialogBottom"
                                    @mouseenter="mouseenterAll"
                                    @mouseleave="mouseleaveAll">
                                   <div class="deleteImgAll" v-show="removeShow&&checkedNodes.length>0" @click="removeAll">
                                       <i class="el-icon-close"></i>
                                   </div>
                                   <span class="dialogBottomItem"
                                         v-for="item in checkedNodes"
                                         :key="item.detailCode"
                                         @mouseenter="mouseenter(item)"
                                         @mouseleave="mouseleave(item)"
                                   >
                             <div class="delete-img" v-show="item.show" @click="remove(item.detailCode)">
                                 <i class="el-icon-close"></i>
                             </div>
                             <div class="companyImg" v-if="checkedNodes.length>0">
                                <span v-if="item.detailType==1"><i class="iconfont icon-jigouyinhang"></i></span>
                                <span v-else-if="item.detailType==2"><i class="iconfont icon-bumen"></i></span>
                                 <span v-else><i class="iconfont icon-renyuan1"></i></span>
                             </div>
                             <div class="itemText">{{item.detailName}}</div>
                         </span>
                               </div>
                               <div class="dialog_button">
                                   <el-button type="primary" @click="submitFormTwo">确定 <span v-if="checkedNodes.length>0">({{checkedNodes.length}})</span></el-button>
                                   <el-button @click="closeDialogTwo">取消</el-button>
                               </div>
                           </div>
                       </el-dialog>

data定义的

//搜索
searchKey:'', //搜索tree的key值
type:'1,2,3,4', //type:1-群组,2-组织/部门,3-省区,4-员工信息;
userCheckAllList:[], //组装循环数据结构
//添加,修改
dialogForm: {
                   groupName:'',//群组名
                   groupCode:'',//群组code
                   mono:'',//备注
                   status:1,//是否启用,1:是,0:否
                   groupDetailVoList:[]//选中群组人员
},
//添加,修改里面的弹窗  组织成员
               dialogFormTwo:{
                   //选中群组人员
               },
props: {
                   label: 'orgName',
                   children: 'children'
               },
               removeShow:false,
               checkedNodes:[],//选中的数据
               tempCheck:[],//临时数组
               tempAllCheck:[],//全选临时数组
               checkedNodesEdit:[],//编辑回显后台返回来的数据
               userList:[],
               checkedNameList:[],
               isDisabled:false,//默认可编辑
               isDetailPage: false, // 是否是详情页
               newUserList:[],

methods方法里面的

//tree 搜索
            handleGroupKey(val){
                this.searchKey= val
            },
            //搜索
            getSearchGroupKey(){
                if (this.searchKey === '') {
                    return false;
                }
                let params={
                    key:this.searchKey,
                    type:this.type
                }
                groupMessageApi.getGroupSearchOrg(params).then(res=>{
                    if(res.status==0){
                        if(res.data.length>0){
                            //组装数据结构
                            this.userList=[];
                            if(res.data&&res.data.length>0){
                                res.data.map(item=>{
                                    this.userList.push({
                                        detailCode:item.deptCode,
                                        detailName:item.orgName,
                                        detailType:item.deptType,
                                        checkedFlag:false
                                    })
                                })
                            }

                            let dataList=this.userList; //点击的时候获取所有的接口的数据
                            let getCheckList=[]; //选中相同的数据
                            dataList.map(item=>{
                                this.checkedNameList.filter(value=>{
                                    if(item.detailCode===value){
                                        getCheckList.push(item)
                                    }
                                })
                            })
                            let noCheckList = dataList.filter(item => !this.checkedNameList.some(ele=>ele===item.detailCode)); //没有选中的数据
                            let arrAllDataList=getCheckList.concat(noCheckList) //code相等并且选中的和没有选中的合并,就是当前点击这一项的回显的所有数据
                            this.userCheckAllList=[]
                            this.userCheckAllList.push({
                                id: 0,
                                menuDesc: '全选',
                                isIndeterminateUser:getCheckList.length>0&&getCheckList.length<arrAllDataList.length,
                                checkAllUser:getCheckList.length===arrAllDataList.length || getCheckList.length > arrAllDataList.length,
                                checkedNameList:this.checkedNameList,
                                userList: dataList,
                            })
                        }
                    }else{
                        this.$message.error(res.message)
                    }
                }) .catch((error) => {
                    console.log('/announceMng/addEditAnnounce内容修改/添加', error)
                });
            },
//全选人员
            handleCheckAllChange(val){
              let arr=[]
               this.userCheckAllList.map(item=>{
                    item.userList&&item.userList.map(ele=>{
                        return arr.push(ele.detailCode);
                    })
                   item.checkedNameList = val ? arr : [];
                })
                if(val) {
                    let myArr=[];
                    this.userCheckAllList[0].userList.forEach(item=>{
                        myArr.push({
                            detailName: item.detailName,
                            detailCode: item.detailCode,
                            detailType: item.detailType
                        });
                        // 建个临时数组
                        this.tempAllCheck = myArr.concat([])
                        if (this.checkedNodes.length === 0) {
                            this.checkedNodes = this.checkedNodes.concat(this.tempAllCheck)
                        } else { //取消选中
                            //去重之后再合并
                            for (let i = 0; i < this.checkedNodes.length; i++) {
                                for (let j = 0; j < this.tempAllCheck.length; j++) {
                                    if (this.checkedNodes[i].detailCode == this.tempAllCheck[j].detailCode) {
                                        this.tempAllCheck.splice(j, 1);
                                    }
                                }
                            }
                            this.checkedNodes = this.checkedNodes.concat(this.tempAllCheck);
                        }
                    })
                }else{
                    this.checkedNodes =[]
                }
            },
            //右边的人员搜索出来的结果(单选)
            handleChangeSearch(data){
                //判断是否选中还是取消
                if(this.userCheckAllList.length>0){
                    this.userCheckAllList[0].userList.forEach(item=>{
                        let arr = []
                        if(item.detailCode==data.detailCode) {
                            if (this.userCheckAllList[0].checkedNameList.includes(data.detailCode)) {//选中
                                arr.push({
                                    detailName: item.detailName,
                                    detailCode: item.detailCode,
                                    detailType: item.detailType
                                });
                                // 建个临时数组
                                this.tempCheck = arr.concat([])
                                if (this.checkedNodes.length === 0) {
                                    this.checkedNodes = this.checkedNodes.concat(this.tempCheck)
                                } else { //取消选中
                                    //去重之后再合并
                                    for (let i = 0; i < this.checkedNodes.length; i++) {
                                        for (let j = 0; j < this.tempCheck.length; j++) {
                                            if (this.checkedNodes[i].detailCode == this.tempCheck[j].detailCode) {
                                                this.tempCheck.splice(j, 1);
                                            }
                                        }
                                    }
                                    this.checkedNodes = this.checkedNodes.concat(this.tempCheck);
                                }
                            } else {
                                this.checkedNodes = this.checkedNodes.filter(val => !(val.detailCode === data.detailCode))
                            }
                        }

                        let checkedItemCode=this.checkedNodes.filter(item => this.userCheckAllList[0].userList.some(ele=>ele.detailCode===item.detailCode)); //交集的数组(选中)
                        this.userCheckAllList[0].checkAllUser = checkedItemCode.length===this.userCheckAllList[0].userList.length ||  checkedItemCode.length > this.userCheckAllList[0].userList.length
                        this.userCheckAllList[0].isIndeterminateUser  =checkedItemCode.length>0&&checkedItemCode.length < this.userCheckAllList[0].userList.length
                    })
                }
            },
            //单个 删除按钮鼠标上去显示,移出隐藏
            mouseenter(data) {
                this.$set(data, 'show', true)
            },
            mouseleave(data) {
                this.$set(data, 'show', false)
            },
            //单个删除
            remove(data){
                this.checkedNodes=this.checkedNodes.filter( item=>!(data===item.detailCode));//单个删除
                this.userCheckAllList.map(item=>{ //单个删除对应的选中的也去掉
                    if(item.checkedNameList){
                        item.checkedNameList=item.checkedNameList.filter(value => !(data===value));
                        if(item.checkedNameList.length===0){
                            item.checkAllUser=false
                            item.isIndeterminateUser = false
                        }else{
                            item.checkAllUser=true
                            item.isIndeterminateUser = false
                        }
                    }
                });
            },
            //全部删除是否显示隐藏
            mouseenterAll(){
                this.removeShow=true
            },
            mouseleaveAll(){
                this.removeShow=false
            },
            //全部删除
            removeAll(){
                this.$nextTick(function () {
                    this.userCheckAllList.map(item=>{
                        item.checkAllUser=false
                        item.isIndeterminateUser=false
                        item.checkedNameList=[] //去掉选中的样式
                    });
                    this.checkedNodes=[]; //数据清空
                });
            },
            // 加载树型组织部门信息
            loadNode(node, resolve) {
                let params = {
                    deptType: node.data == undefined ? 1 : node.data.deptType,
                    orgCode: node.data == undefined ? "FIRST" : node.data.orgCode
                }
                groupMessageApi.organizationsTreeDepts(params).then(res => {
                    if (res.status == 0) {
                        if(res.data){
                            return resolve(res.data.departmentResps)
                        }
                    } else {
                        return this.$message.error(res.message)
                    }
                })
            },
            //添加icon
            renderContent(h, { data }){
                let createElement = arguments[0];
                if (data.deptType == 1) {
                    return createElement('span', [
                        createElement('i', {attrs: {class: 'iconfont icon-jigouyinhang'}}),
                        createElement('span', "     "),
                        createElement('span', arguments[1].node.label)
                    ]);
                }else if(data.deptType == 2){
                    return createElement('span', [
                        createElement('i', {attrs: {class: 'iconfont icon-bumen'}}),
                        createElement('span', "     "),
                        createElement('span', arguments[1].node.label)
                    ]);
                }else{
                    return createElement('span', [
                        createElement('i', {attrs: {class: 'iconfont icon-renyuan'}}),
                        createElement('span', "     "),
                        createElement('span', arguments[1].node.label)
                    ]);
                }
            },
            //节点被点击时回调
            handleNodeClick(event){
                let params = {
                    deptType: event.deptType,
                    orgCode: event.orgCode
                }
                groupMessageApi.organizationsTreeDepts(params).then(res => {
                    if (res.status == 0) {
                        if(res.data){
                            let arrUserList=[];
                            let arrDeptList=[];
                            //部门和人员同时存在时
                            if(res.data.deptUsers&&res.data.deptUsers.length>0 || res.data.departmentResps&&res.data.departmentResps.length>1){
                                res.data.deptUsers.map(item=>{
                                    arrUserList.push({
                                        detailCode:item.userCode,
                                        detailName:item.userName,
                                        detailType:null,
                                        checkedFlag:false
                                    })
                                    return arrUserList
                                })
                                res.data.departmentResps.map(item=>{
                                    arrDeptList.push({
                                        detailCode:item.deptCode,
                                        detailName:item.orgName,
                                        detailType:item.deptType,
                                        checkedFlag:false
                                    })
                                    return arrDeptList
                                })
                                let dataList=arrUserList.concat(arrDeptList); //点击的时候获取所有的接口的数据
                                let getCheckList=[]; //选中相同的数据
                                dataList.map(item=>{
                                    this.checkedNameList.filter(value=>{
                                        if(item.detailCode===value){
                                            getCheckList.push(item)
                                        }
                                    })
                                });
                                let noCheckList = dataList.filter(item => !this.checkedNameList.some(ele=>ele===item.detailCode)); //没有选中的数据
                                let arrAllDataList=getCheckList.concat(noCheckList) //code相等并且选中的和没有选中的合并,就是当前点击这一项的回显的所有数据
                                //回显
                                this.checkedNameList=[]  //回显人员
                                this.checkedNodes= this.checkedNodes.map(item=>{
                                    this.checkedNameList.push(item.detailCode)
                                    let obj={
                                        detailName:item.detailName,
                                        detailCode:item.detailCode,
                                        detailType:item.detailType
                                    };
                                    return obj
                                });

                                this.userCheckAllList=[]
                                this.userCheckAllList.push({
                                    id: 0,
                                    menuDesc: '全选',
                                    isIndeterminateUser:getCheckList.length>0&&getCheckList.length<arrAllDataList.length,
                                    checkAllUser:getCheckList.length===arrAllDataList.length || getCheckList.length > arrAllDataList.length,
                                    checkedNameList:this.checkedNameList,
                                    userList: dataList,
                                })
                            }
                        }
                    } else {
                        return this.$message.error(res.message)
                    }
                })
            },
            //tree change事件
            handleCheckChange() {
                this.checkedNodes = this.$refs.tree.getCheckedNodes()
            },

//根据groupCode查询人员
            groupList(groupCode){
                groupMessageApi.getQueryGroupDetail({groupCode:groupCode}).then(res => {
                        if (res.status === 0) {
                            this.checkedNodesEdit=res.data;
                            this.checkedNodes=[];
                            this.checkedNameList=[]  //回显人员
                            this.checkedNodes=this.checkedNodesEdit.map(item=>{
                                this.checkedNameList.push(item.detailCode)
                                let obj={
                                    detailName:item.detailName,
                                    detailCode:item.detailCode,
                                    detailType:item.detailType
                                };
                                return obj
                            });
                        } else {
                            this.$message.error(res.message)
                        }
                    })
            },

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354

推荐阅读更多精彩内容