el-tree的操作(特殊上移,下移)(合起,展开)

389 阅读2分钟

场景:

如果后台返回的树数据排序是按照其中的某一个属性来排序的,这里以number举例,如下图所示

企业微信截图_17363041781097.png

那么移动的时候就要更新他的number值,以及原本数据位置

上下移动

(vue3+elementplus) tip:allMenu为菜单数据且为对象数组(非嵌套)即上图所示 currentNode(选中节点)和currentMenu(选中菜单)为业务需要,不需要可删除

updateNumber(data,oldStr,newStr){//data为某一项数据多维数组
    function startsWith(str, prefix) {  
        return str.indexOf(prefix) === 0;  
    }  

    // Base case: if data is null or undefined, return immediately  
    if (!data) return;  

    // Check if the current node's number starts with oldStr  
    if (data.number && startsWith(data.number.toString(), oldStr)) {  
        // Update the number by replacing the oldStr prefix with newStr  
        data.number = newStr + data.number.toString().slice(oldStr.length);  
    }  

    // Recursively process the children  
    if (data.children && data.children.length > 0) {  
        data.children=data.children.map(child => {  
            this.updateNumber(child, oldStr, newStr);  
            return child;
        });  
    }  
},
updateallMenuNumber(data,oldStr,newStr){//data为全部数据一维数组
    function startsWith(str, prefix) {  
        return str.toString().startsWith(prefix);  
    } 
    const matchedOld = data.filter(item => item.number.startsWith(oldStr));  
    const matchedNew = data.filter(item => item.number.startsWith(newStr));  

    const indexOld = data.findIndex(item => item.number.startsWith(oldStr));  
    const indexNew = data.findIndex(item => item.number.startsWith(newStr));  

    if (indexOld !== -1 && indexNew !== -1) {  
        let firstArr=data.slice(0,Math.min(indexOld,indexNew))
        let endArr=[]
        if(indexNew>indexOld){//上移
            endArr=data.slice((indexNew+matchedNew.length),data.length)
            data=firstArr.concat(matchedNew)
            data=data.concat(matchedOld)
            data=data.concat(endArr)
        }else if(indexNew<indexOld){//下移
            endArr=data.slice((indexOld+matchedOld.length),data.length)
            data=firstArr.concat(matchedOld)
            data=data.concat(matchedNew)
            data=data.concat(endArr)
        }
    }  


    return data.map(item => {  
        if (item.number !== undefined) {  
            let newNumber;  
            if (startsWith(item.number.toString(), oldStr)) {  
                newNumber = newStr + item.number.toString().slice(oldStr.length);
                item.number=newNumber
            } else if (startsWith(item.number.toString(), newStr)) {  
                newNumber = oldStr + item.number.toString().slice(newStr.length);  
                item.number=newNumber
            } else {  
                newNumber = item.number;  
            }  
        }   
        return item;  
    });  
},
upMenu(){//上移菜单
    const parent = this.$refs.tree.getNode(this.$refs.tree.getCurrentKey()).parent;
    const children = parent.data.children || parent.data;
    const cIndex = children.findIndex(d => d.menuId === this.currentMenu.menuId);
    if (parent.level === 0 && cIndex === 0) {
        return;
    }
    else if (
        (parent.level === 0 && cIndex !== 0) ||
        (parent.level !== 0 && cIndex !== 0)
    ) {
        const tempChildrenNodex1 = JSON.parse(JSON.stringify(children[cIndex - 1]));

        const tempChildrenNodex2 = JSON.parse(JSON.stringify(children[cIndex]));

        children[cIndex]=tempChildrenNodex1
        children[cIndex-1]=tempChildrenNodex2
        let num1=JSON.parse(JSON.stringify(children[cIndex-1].number))
        let num=JSON.parse(JSON.stringify(children[cIndex].number))
        this.updateNumber(children[cIndex],num,num1)
        this.updateNumber(children[cIndex-1],num1,num)
        this.allMenu=this.updateallMenuNumber(this.flattenTree(this.data),num,num1)
        this.currentNode=this.$refs.tree.getNode(this.$refs.tree.getCurrentKey())
        this.currentMenu=this.$refs.tree.getCurrentNode()
        this.$nextTick(()=>{ //此处为控制上下移动按钮是否可用
            if (cIndex-1 === 0) {
                this.upDisabled=true
                this.downDisabled=false
            }else if(cIndex-1<children.length-1){
                this.upDisabled=false
                this.downDisabled=false
            }
            //高亮行控制
            if(this.$refs.tree)this.$refs.tree.setCurrentKey(children[cIndex-1].menuId)
        })
    }

},
downMenu(){//下移菜单
    const parent = this.$refs.tree.getNode(this.$refs.tree.getCurrentKey()).parent;
    const children = parent.data.children || parent.data;
    const cIndex = children.findIndex(d => d.menuId === this.currentMenu.menuId);
    if (parent.level === 0 && cIndex === children.length-1) {
        return;
    }
    else if (
        (parent.level === 0 && cIndex !== children.length-1) ||
        (parent.level !== 0 && cIndex !== children.length-1)
    ) {
        const tempChildrenNodex1 = JSON.parse(JSON.stringify(children[cIndex + 1]));

        const tempChildrenNodex2 = JSON.parse(JSON.stringify(children[cIndex]));

        children[cIndex]=tempChildrenNodex1
        children[cIndex+1]=tempChildrenNodex2
        let num1=JSON.parse(JSON.stringify(children[cIndex+1].number))
        let num=JSON.parse(JSON.stringify(children[cIndex].number))
        this.updateNumber(children[cIndex],num,num1)
        this.updateNumber(children[cIndex+1],num1,num)
        this.allMenu=this.updateallMenuNumber(this.flattenTree(this.data),num,num1)
        this.currentNode=this.$refs.tree.getNode(this.$refs.tree.getCurrentKey())
        this.currentMenu=this.$refs.tree.getCurrentNode()
        this.$nextTick(()=>{
            if (cIndex+1 === children.length-1) {
                this.downDisabled=true
                this.upDisabled=false
            }else if(cIndex+1>0){
                this.upDisabled=false
                this.downDisabled=false
            }
            if(this.$refs.tree)this.$refs.tree.setCurrentKey(children[cIndex+1].menuId)
        })
    }
},

非特殊情况可参考elementPlus的Api Tree 树形控件 | Element Plus 其中的remove与insertBefore或insertAfter相互搭配进行上下移动

思路:记录原节点,remove删除原节点,将记录的节点通过insertBefore或insertAfter插入树中达到效果

合起与展开

el-tree 设置属性

:default-expanded-keys="expandedRightData"

:key="treeKey"

:default-expand-all="isExpand"

rowOpenORFold(isExpand) {// 展开或折叠全部的方法
    this.treeKey = +new Date()
    this.isExpand = isExpand
    if(!this.isExpand) this.expandedRightData=[]
    this.$nextTick(()=>{
        this.rightTreeLoading=false
    })
},

通过调用rowOpenORFold(是否展开:true||false)来控制该树项的展开与合起

感谢阅读