需求

这里的UI使用的是Element-Plus

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*

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

*/

这里模拟了待转化的字符串数组如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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",
]

转化后的目标结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
[
{
"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文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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方法即可。

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

let confirmTreeList: TreeNode[] = []

confirmTreeList = array2Tree(TargetKeyLists)

3.效果如下:

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

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

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

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