头图
原文链接:[如何将路径字符串数组(string[])转成树结构(treeNode[])?](https://fe32.top/articles/vue20004/)

需求

这里的UI使用的是Element-Plus

将一个路径字符串数组(当然也可能是其他目标字符串数组),渲染成

/*

source:
  /a/b/c/d/e
  /a/b/e/f/g
  /a/b/h
  /a/i/j
  /a/i/k

what I need:
       a
     /   \
    b     i
   /|\   / \
  c e h j   k
  | |
  d f
  | |
  e g   

*/
这里模拟了待转化的字符串数组如下:
let TargetKeyLists = [
    "D:\\$RECYCLE.BIN\\S-1-5-21-2980625316-768050560-104202119-1001\\$I0KVI2C.css",
    "D:\\$RECYCLE.BIN\\S-1-5-21-2980625316-768050560-104202119-1001\\$I61JY0M.php",
    "D:\\$RECYCLE.BIN\\S-1-5-21-2980625316-768050560-104202119-1001\\$I8IC15E.html",
    "D:\\$RECYCLE.BIN\\S-1-5-21-2980625316-768050560-104202119-1001\\$I9UTNI9.ico",
    "D:\\Program Files\\Sandboxie",
    "D:\\fbs\\xampp-windows-x64-8.2.0-0-VS16-installer.exe",
    "D:\\fcstor\\.svn",
    "D:\\xampp\\MercuryMail",
    "D:\\xampp\\anonymous",
    "D:\\xampp\\apache",
    "C:\\$Recycle.Bin\\S-1-5-18",
    "C:\\$Recycle.Bin\\S-1-5-21-2980625316-768050560-104202119-1001",
    "C:\\$Recycle.Bin\\S-1-5-21-2980625316-768050560-104202119-500",
    "C:\\BOOTNXT",
]

转化后的目标结构如下:

[
    {
        "label": "D:",
        "children": [
            {
                "label": "$RECYCLE.BIN",
                "children": [
                    {
                        "label": "S-1-5-21-2980625316-768050560-104202119-1001",
                        "children": [
                            {
                                "label": "$I0KVI2C.css",
                                "children": []
                            },
                            {
                                "label": "$I61JY0M.php",
                                "children": []
                            },
                            {
                                "label": "$I8IC15E.html",
                                "children": []
                            },
                            {
                                "label": "$I9UTNI9.ico",
                                "children": []
                            }
                        ]
                    }
                ]
            },
            {
                "label": "Program Files",
                "children": [
                    {
                        "label": "Sandboxie",
                        "children": []
                    }
                ]
            },
            {
                "label": "fbs",
                "children": [
                    {
                        "label": "xampp-windows-x64-8.2.0-0-VS16-installer.exe",
                        "children": []
                    }
                ]
            },
            {
                "label": "fcstor",
                "children": [
                    {
                        "label": ".svn",
                        "children": []
                    }
                ]
            },
            {
                "label": "xampp",
                "children": [
                    {
                        "label": "MercuryMail",
                        "children": []
                    },
                    {
                        "label": "anonymous",
                        "children": []
                    },
                    {
                        "label": "apache",
                        "children": []
                    }
                ]
            }
        ]
    },
    {
        "label": "C:",
        "children": [
            {
                "label": "$Recycle.Bin",
                "children": [
                    {
                        "label": "S-1-5-18",
                        "children": []
                    },
                    {
                        "label": "S-1-5-21-2980625316-768050560-104202119-1001",
                        "children": []
                    },
                    {
                        "label": "S-1-5-21-2980625316-768050560-104202119-500",
                        "children": []
                    }
                ]
            },
            {
                "label": "BOOTNXT",
                "children": []
            }
        ]
    }
]

步骤

1.在utils文件夹下新建index.ts文件。

interface TreeNode {
    label: string
    children: TreeNode[]
}

// 循环构建子节点
const buildChildrenNode = (children: TreeNode[], nodeArray: string[]) => {
    for (let i in nodeArray) {
        let _i: number = Number(i)
        let node: TreeNode = {
            label: nodeArray[_i],
            children: []
        }
        if (_i != nodeArray.length) {
            node.children = []
        }
        if (children.length == 0) {
            children.push(node)
        }
        let isExist = false
        for (let j in children) {
            if (children[j].label == node.label) {
                if (_i != nodeArray.length - 1 && !children[j].children) {
                    children[j].children = []
                }
                children = _i == nodeArray.length - 1 ? children : children[j].children
                isExist = true
                break
            }
        }
        if (!isExist) {
            children.push(node)
            if (_i != nodeArray.length - 1 && !children[children.length - 1].children) {
                children[children.length - 1].children = []
            }
            children = _i == nodeArray.length - 1 ? children : children[children.length - 1].children
        }
    }
}
/**
 * @description: string[] ->  treeNode[]
 * @param {string} list 资源路径数组
 * @param {string} clientLabel 是否需要在最外面还要套一层(exam:所属客户端)
 * @return { treeNode[] }
 */
export const array2Tree = (list: string[], clientLabel?: string) => {
    let targetList: TreeNode[] = []
    list.map(item => {
        let label = item
        let nodeArray: string[] = label.split('\\').filter(str => str != '')
        // 递归
        let children: TreeNode[] = targetList
        // 构建根节点
        if (children.length == 0) {
            let root: TreeNode = {
                label: nodeArray[0],
                children: []
            }
            if (nodeArray.length > 1) {
                root.children = []
            }
            children.push(root)
            buildChildrenNode(children, nodeArray)
        } else {
            buildChildrenNode(children, nodeArray)
        }
    })
    if (!clientLabel) {
        return targetList
    } else {
        const newArr = [{
            label: clientLabel,
            children: targetList
        }]
        return newArr
    }
}

2.在目标页面中引入并调用array2Tree方法即可。

<template>
    <el-tree :data="confirmTreeList" default-expand-all />
</template>
import { array2Tree } from '@/utils/index'

let confirmTreeList: TreeNode[] = []

confirmTreeList = array2Tree(TargetKeyLists)

3.效果如下:

这里说明一下,array2Tree()方法中的clientLabel参数其实可要可不要,也可继续扩展,根据自身业务而定。

比如我想最后实现的效果如下图所示:

所以在第2步中传入clientLabel即可:

confirmTreeList = array2Tree(TargetKeyLists,'test(192.168.0.213)')

唐志远
25 声望5 粉丝