sf-utils2 sf-utils2
版本v3.3.3-beta1
首页
  • 01.快速开始 🔥
  • 02.基础-Base
  • 03.对象-Object
  • 04.数组-Array
  • 05.方法-Function
  • 06.字符串-String
  • 07.数学-Math
  • 08.dom
  • 09.拓展
  • webpack5.x教程学习 (opens new window)
  • 例子
  • 教程 🔥
  • 例子配置
企业级后台模版 (opens new window)
版本v3.3.3-beta1
首页
  • 01.快速开始 🔥
  • 02.基础-Base
  • 03.对象-Object
  • 04.数组-Array
  • 05.方法-Function
  • 06.字符串-String
  • 07.数学-Math
  • 08.dom
  • 09.拓展
  • webpack5.x教程学习 (opens new window)
  • 例子
  • 教程 🔥
  • 例子配置
企业级后台模版 (opens new window)
  • 快速开始

  • 基础-Base

  • 对象-Object

  • 数组-Array✨✨✨

    • 序言 👏
    • uniq 【数组去重】
    • arrayToMap 【数组转成Map】
    • arrayToObj 【数组转成obj】
    • chunk 【数组切割】
    • compact 【去除数组中无效值】
    • remove 【数组中移除一个元素】
    • shuffle 【数组随机打乱】
    • groupBy 【分组】
    • compactIsNoNullable 【去除数组中null/undefined/NaN】
    • arrayDiff【比较数组差异】🔥🔥
    • differenceBy【获取新增数组】🔥
    • intersection 【数组交集】
    • matchSubListGroup
    • listToTree【列表转树形】🔥🔥🔥
    • treeToList【树型转列表】🔥🔥🔥
    • eachTree【遍历树形结构】🔥🔥🔥
      • 1.1 示例 根据 callbackFn 自定义格式化方法,排序
      • 1.2 示例 根据 callbackList 和 callbackItem 回调函数,输出结果
      • 1.3 示例 先子节点到父节点 递归遍历【莫发达提供】
      • 2.入参说明
        • 主入参
        • props 对象
        • callbackList 回调函数,接收参数
        • callbackItem 回调函数,接收参数
      • 3.源码
    • filterTree【过滤树形结构】🔥🔥🔥
    • childNodesInList【列表中获取某个下所有后代节点】🔥
    • parentNodesInTree【tree中获取所有祖先节点】 🔥
    • formatStrategyIdsInTree【树形数据中只选中父节点】 🔥
    • range 【序号列表生成函数】
  • 方法-Function

  • 字符串-String

  • 数学-Math

  • 文件-Buffer

  • 节点-dom

  • 拓展

  • nodejs

目录

eachTree【遍历树形结构】🔥🔥🔥

描述

递归遍历 Tree(树状结构),支持函数式编程(函数回调),高扩展常用

// eachTree 为每个节点增加属性如下,__depth__、__id__、__level__、__pId__、__rootNode__
// children: (3) [{…}, {…}, {…}]
// id: 1
// name: "香蕉"
// order: 2
// parentId: null
// __depth__: 1  // 当前节点深度
// __id__: "0-1" // 节点经过的路径
// __level__: 1 // 当前节点深度
// __parentNode__: {id: 1, name: '香蕉', parentId: null, order: 2, children: Array(3), …} // 当前父节点
// __pId__: "0" // 父节点经过的路径
// __rootNode__: {id: 1, name: '香蕉', parentId: null, order: 2, children: Array(3), …} // 顶层根节点
1
2
3
4
5
6
7
8
9
10
11
12

# 1.1 示例 根据 callbackFn 自定义格式化方法,排序

源码,点开查看 👈
let tree = [
  {
    id: 1,
    name: '香蕉',
    pId: null,
    order: 10,
    children: [
      {
        id: 1001,
        name: '香蕉A',
        pId: 1,
        children: [
          {
            id: 1001001,
            name: '香蕉A-儿子',
            pId: 1001,
            children: [
              {
                id: 1001001001,
                name: '香蕉A-儿子-儿子',
                pId: 1001001
              }
            ]
          }
        ]
      },
      {
        id: 1002,
        name: '香蕉B',
        pId: 1,
        order: 21,
        children: [
          {
            id: 1002002,
            name: '香蕉B-儿子',
            pId: 1002
          }
        ]
      },
      {
        id: 1003,
        name: '香蕉C',
        pId: 1,
        order: 3,
        children: [
          {
            id: 1003003,
            name: '香蕉C-儿子',
            pId: 1003
          }
        ]
      }
    ]
  },
  {
    id: 2,
    name: '苹果',
    pId: null,
    order: 2,
    children: [
      {
        id: 1004,
        name: '苹果A',
        pId: 2,
        children: [
          {
            id: 1004004,
            name: '苹果A-儿子',
            pId: 1004
          }
        ]
      },
      {
        id: 1007,
        name: '苹果D',
        order: 5,
        pId: 2
      },
      {
        id: 1008,
        name: '苹果D',
        order: 15,
        pId: 2
      },
      {
        id: 1009,
        name: '苹果C',
        order: 10,
        pId: 2
      }
    ]
  }
]

// 根据callbackFn自定义格式化方法,排序
console.log(
  eachTree({
    tree: tree,
    props: { children: 'children' },
    callbackList: (list, parentObj) => {
      // list:每个节点下子节点数组 parentObj:父节点对象
      console.log('回调函数@callbackList', list, parentObj)
      list.sort((a, b) => a.order - b.order)
    }
  })
)
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
104
105
106

输出结果

⚠️ 注意

这边在eachTree方法时,会默认给每个节点加上 __id__(节点经过路径) 、 __pId__(父节点经过的路径)、__depth__(当前节点深度)、__rootNode__(最上层,根节点对象) ,__id__ 每一个子节点唯一值,__pId__ 每一个子节点中的父节点值, 你会发现这边的 __id__ 看起来是有规则的,它是下标索引为基值,比如 __id__ 是 0-1-1-1-1 时,表面它处于第 4 层、之前途径的路径是 0-1、0-1-1、 0-1-1-1, 这样方便平时业务中做其他操作,比如要获取每个子节点所有途经的节点集合,我们只需要遍历刚才的 0-1、0-1-1、 0-1-1-1 去 list 中找到 __id__ 是其中之一。是不是感觉很方便?😁
同时还会给每个节点默认加上__depth__(当前节点深度)、__rootNode__(最上层,根节点对象) v3.3.0+ 每一个节点都会增加 __prevNode__(当前节点相邻的上一个节点)属性、__nextNode__(当前节点相邻的下一个节点)属性。

# 1.2 示例 根据 callbackList 和 callbackItem 回调函数,输出结果

源码,点开查看 👈
import { eachTree } from 'sf-utils2'
let tree = [
  {
    id: 1,
    name: '香蕉',
    pId: null,
    order: 10,
    children: [
      {
        id: 1001,
        name: '香蕉A',
        pId: 1,
        children: [
          {
            id: 1001001,
            name: '香蕉A-儿子',
            pId: 1001,
            children: [
              {
                id: 1001001001,
                name: '香蕉A-儿子-儿子',
                pId: 1001001
              }
            ]
          }
        ]
      },
      {
        id: 1002,
        name: '香蕉B',
        pId: 1,
        order: 21,
        children: [
          {
            id: 1002002,
            name: '香蕉B-儿子',
            pId: 1002
          }
        ]
      },
      {
        id: 1003,
        name: '香蕉C',
        pId: 1,
        order: 3,
        children: [
          {
            id: 1003003,
            name: '香蕉C-儿子',
            pId: 1003
          }
        ]
      }
    ]
  },
  {
    id: 2,
    name: '苹果',
    pId: null,
    order: 2,
    children: [
      {
        id: 1004,
        name: '苹果A',
        pId: 2,
        children: [
          {
            id: 1004004,
            name: '苹果A-儿子',
            pId: 1004
          }
        ]
      },
      {
        id: 1007,
        name: '苹果D',
        order: 5,
        pId: 2
      },
      {
        id: 1008,
        name: '苹果D',
        order: 15,
        pId: 2
      },
      {
        id: 1009,
        name: '苹果C',
        order: 10,
        pId: 2
      }
    ]
  }
]

// 根据callbackFn自定义格式化方法,排序
eachTree({
  tree: tree,
  props: { children: 'children' },
  callbackList: (list, parentObj) => {
    // list:每个节点下子节点数组 parentObj:父节点对象
    console.log('回调函数的值@callbackList', list, parentObj)
    list.sort((a, b) => a.order - b.order)
    // 返回true时,表示告诉 eachTree 终止调用[callbackList]循环,即不再调用该callbackList方法
  },
  callbackItem: (item, index, list, parentObj) => {
    // item => 当前树节点, index => 当前树节点索引, list => 当前树节点数组, parentObj => 父节点
    console.log('回调函数的值@callbackItem', item, index, list, parentObj)
    // 其中item输出的值是:
    // children: (3) [{…}, {…}, {…}]
    // id: 1
    // name: "香蕉"
    // order: 2
    // parentId: null
    // __depth__: 1  // 当前节点深度
    // __id__: "0-1" // 节点经过的路径
    // __level__: 1 // 当前节点深度
    // __pId__: "0" // 父节点经过的路径
    // __parentNode__: {id: 1, name: '香蕉', parentId: null, order: 2, children: Array(3), …} // 当前父节点
    // __rootNode__: {id: 1, name: '香蕉', parentId: null, order: 2, children: Array(3), …} // 顶层根节点
    return true // 返回true时,表示告诉 eachTree 终止当前节点循环,不再进行其子孙节点循环,但其兄弟节点还是要走[callbackItem]逻辑循环。
  }
})
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

输出结果

# 1.3 示例 先子节点到父节点 递归遍历【莫发达提供】

注:以前我没注意 都是从父到子进行递归,先子节点到父节点 递归遍历【莫发达提供】,默认是先父节点到子节点。

源码,点开查看 👈
import { eachTree } from 'sf-utils2'
let tree = [
  {
    id: 1,
    name: '香蕉',
    pId: null,
    order: 10,
    children: [
      {
        id: 1001,
        name: '香蕉A',
        pId: 1,
        children: [
          {
            id: 1001001,
            name: '香蕉A-儿子',
            pId: 1001,
            children: [
              {
                id: 1001001001,
                name: '香蕉A-儿子-儿子',
                pId: 1001001
              }
            ]
          }
        ]
      },
      {
        id: 1002,
        name: '香蕉B',
        pId: 1,
        order: 21,
        children: [
          {
            id: 1002002,
            name: '香蕉B-儿子',
            pId: 1002
          }
        ]
      },
      {
        id: 1003,
        name: '香蕉C',
        pId: 1,
        order: 3,
        children: [
          {
            id: 1003003,
            name: '香蕉C-儿子',
            pId: 1003
          }
        ]
      }
    ]
  },
  {
    id: 2,
    name: '苹果',
    pId: null,
    order: 2,
    children: [
      {
        id: 1004,
        name: '苹果A',
        pId: 2,
        children: [
          {
            id: 1004004,
            name: '苹果A-儿子',
            pId: 1004
          }
        ]
      },
      {
        id: 1007,
        name: '苹果D',
        order: 5,
        pId: 2
      },
      {
        id: 1008,
        name: '苹果D',
        order: 15,
        pId: 2
      },
      {
        id: 1009,
        name: '苹果C',
        order: 10,
        pId: 2
      }
    ]
  }
]

// 根据callbackFn自定义格式化方法,排序
eachTree({
  tree: tree,
  props: { children: 'children' },
  traversalOrder: 'postorder',
  callbackItem: (item, index, list, parentObj) => {
    // item:当前节点对象 parentObj:父节点对象
    console.log('回调函数@callbackItem', item, index, list, parentObj)
  }
})
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
104
105

输出结果

# 2.入参说明

# 主入参

参数 说明 类型 是否必填 默认值
tree 原数据(要转换的数据集) Array 是
props 自定义字段键名,详情见下 👇 Object 否
callbackList 每次列表循环回调函数,详情见下 👇 Function 否 null
callbackItem 每次列表每一项回调函数,详情见下 👇 Function 否 null
isDeepClone 是否要深拷贝原 tree 对象,默认true Boolean 否 true
retainField 每条数据上要保留的字段 ('__rootNode__', '__pId__', '__level__')[] 否 []
traversalOrder 树的遍历顺序 v3.2.4+,感谢莫发达童鞋提出意见 preorder(先进行父->子 默认)、postorder(后进行子->父) 否 preorder

# props 对象

参数 说明 类型 是否必填 默认值
children 定义children键名 String 否 children
order 是否转化树形时排序 Boolean 否 false
orderField 定义排序键名 String 否 sort
orderBy 定义排序方向键名,可选值
asc(升序) desc(降序)
String 否 asc

# callbackList 回调函数,接收参数

参数 说明 类型 是否必填 默认值
list 当前树节点数组 Array 否
parentObj 父节点对象 Object 否

# callbackItem 回调函数,接收参数

参数 说明 类型 是否必填 默认值
item 当前树节点 Array 否
index 当前树节点索引 Number 否
list 当前树节点数组 Array 否
parentObj 父节点对象 Array 否

# 3.源码

import merge from '@/object/merge'
import _helperTreeBase from '../_helper/_helperTreeBase.js'

/**
 * 从树结构中遍历
 * @param tree
 * @param callbackFn
 */
function eachTree({
  tree = [],
  props = { children: 'children', order: false, orderField: 'order', orderBy: 'asc' },
  callbackList,
  callbackItem,
  isDeepClone = true
}) {
  let defaultOptions = {
    children: 'children',
    order: false,
    orderField: 'order',
    orderBy: 'asc'
  }
  props = merge({}, defaultOptions, props)
  return _helperTreeBase({ props, callbackList, callbackItem, tree, isDeepClone })
}

export default eachTree
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
上次更新: 2025/01/11, 15:37:45
treeToList【树型转列表】🔥🔥🔥
filterTree【过滤树形结构】🔥🔥🔥

← treeToList【树型转列表】🔥🔥🔥 filterTree【过滤树形结构】🔥🔥🔥→

Theme by Vdoing | Copyright © 2022-2025 bianpengfei
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×