tree.ts 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /**
  2. * @description: 列表转树形列表
  3. * @example
  4. listToTree(cloneDeep(list))
  5. listToTree(cloneDeep(list), {
  6. rootWhere: (parent, self) => {
  7. return self.parentId === 0
  8. },
  9. childsWhere: (parent, self) => {
  10. return parent.id === self.parentId
  11. },
  12. addChilds: (parent, childList) => {
  13. if (childList?.length > 0) {
  14. parent['children'] = childList
  15. }
  16. }
  17. })
  18. */
  19. export function listToTree(list: any = [], options = {}, data = null) {
  20. const { rootWhere, childsWhere, addChilds } = Object.assign(
  21. {
  22. rootWhere: (parent: any, self: any) => {
  23. return self.parentId === 0
  24. },
  25. childsWhere: (parent: any, self: any) => {
  26. return parent.id === self.parentId
  27. },
  28. addChilds: (parent: any, childList: any) => {
  29. if (childList?.length > 0) {
  30. parent['children'] = childList
  31. }
  32. },
  33. },
  34. options || {}
  35. )
  36. let tree = [] as any
  37. // 空列表
  38. if (!(list?.length > 0)) {
  39. return tree
  40. }
  41. // 顶级
  42. const rootList = list.filter((item: any) => rootWhere && rootWhere(data, item))
  43. if (!(rootList?.length > 0)) {
  44. return tree
  45. }
  46. tree = tree.concat(rootList)
  47. // 子级
  48. tree.forEach((root: any) => {
  49. const rootChildList = list.filter((item: any) => childsWhere && childsWhere(root, item))
  50. if (!(rootChildList?.length > 0)) {
  51. return
  52. }
  53. rootChildList.forEach((item: any) => {
  54. const childList = listToTree(list, { rootWhere: childsWhere, childsWhere, addChilds }, item)
  55. addChilds && addChilds(item, childList)
  56. })
  57. addChilds && addChilds(root, rootChildList)
  58. })
  59. return tree
  60. }
  61. /**
  62. * @description: 将树形列表转换为扁平化数据列表
  63. * @example
  64. toFlatList(tree, (data) => { return data['children'] }, list)
  65. */
  66. export function toFlatList(tree: any, getChilds: any, flatList: any = [], noChildren = true) {
  67. tree.forEach((item: any) => {
  68. flatList.push(item)
  69. const children = getChilds(item)
  70. if (children?.length > 0) {
  71. toFlatList(children, getChilds, flatList, noChildren)
  72. }
  73. if (noChildren) {
  74. delete item.children
  75. }
  76. })
  77. }
  78. /**
  79. * @description: 树形列表转列表无子级
  80. * @example
  81. treeToList(cloneDeep(tree))
  82. treeToList(cloneDeep(tree), (data) => { return data['children'] })
  83. */
  84. export function treeToList(
  85. tree: any = [],
  86. getChilds = (data: any) => {
  87. return data['children']
  88. }
  89. ) {
  90. const list = [] as any
  91. // 空树
  92. if (!(tree?.length > 0)) {
  93. return list
  94. }
  95. toFlatList(tree, getChilds, list)
  96. return list
  97. }
  98. /**
  99. * @description: 树形列表过滤父级或者子级数据
  100. * @example
  101. filterTree(cloneDeep(tree), keyword)
  102. filterTree(cloneDeep(tree), keyword, {
  103. children: 'children',
  104. filterWhere: (item: any, filterword: string) => {
  105. return item.name?.toLocaleLowerCase().indexOf(filterword) > -1
  106. },
  107. })
  108. */
  109. export function filterTree(tree: any = [], keyword: string, options = {}) {
  110. const { children, filterWhere } = Object.assign(
  111. {
  112. children: 'children',
  113. filterWhere: (item: any, word: string) => {
  114. return item.name?.toLocaleLowerCase().indexOf(word) > -1
  115. },
  116. },
  117. options || {}
  118. )
  119. return tree.filter((item: any) => {
  120. if (filterWhere(item, keyword)) {
  121. return true
  122. }
  123. if (item[children]) {
  124. item[children] = filterTree(item[children], keyword, { children, filterWhere })
  125. return item[children].length > 0
  126. }
  127. return false
  128. })
  129. }
  130. /**
  131. * @description: 树形列表转列表包含子级
  132. * @example
  133. treeToListWithChildren(cloneDeep(tree))
  134. treeToListWithChildren(cloneDeep(tree), (data) => { return data['children'] })
  135. */
  136. export function treeToListWithChildren(
  137. tree = [],
  138. getChilds = (data: any) => {
  139. return data['children']
  140. }
  141. ) {
  142. const list = [] as any
  143. // 空树
  144. if (!(tree?.length > 0)) {
  145. return list
  146. }
  147. toFlatList(tree, getChilds, list, false)
  148. return list
  149. }
  150. /**
  151. * @description: 获得自身所有父级列表
  152. * @example
  153. getParents(cloneDeep(items), self)
  154. getParents(treeToList(cloneDeep(items), self))
  155. const parents = getParents(cloneDeep(items), self, (item, self) => {
  156. return item.id === self.parentId
  157. })
  158. */
  159. export function getParents(
  160. list = [],
  161. self: any,
  162. parentWhere = (item: any, self: any) => {
  163. return item.id === self.parentId
  164. },
  165. parents = []
  166. ) {
  167. // 空列表
  168. if (!(list?.length > 0)) {
  169. return parents
  170. }
  171. if (!self) {
  172. return parents
  173. }
  174. const parent = list.find((item) => parentWhere && parentWhere(item, self))
  175. if (parent) {
  176. parents.unshift(parent)
  177. getParents(list, parent, parentWhere, parents)
  178. }
  179. return parents
  180. }
  181. /**
  182. * @description: 获得自身所有父级列表包含自身
  183. * @example
  184. getParentsAndSelf(cloneDeep(items), self)
  185. getParentsAndSelf(treeToList(cloneDeep(items)), self)
  186. const parents = getParentsAndSelf(cloneDeep(items), self, {
  187. selfWhere: (item, self) => {
  188. return item.id === self.id
  189. },
  190. parentWhere: (item, self) => {
  191. return item.id === self.parentId
  192. }
  193. })
  194. */
  195. export function getParentsAndSelf(list = [], self: any, options = {}) {
  196. const { selfWhere, parentWhere } = Object.assign(
  197. {
  198. selfWhere: (item: any, self: any) => {
  199. return item.id === self.id
  200. },
  201. parentWhere: (item: any, self: any) => {
  202. return item.id === self.parentId
  203. },
  204. },
  205. options || {}
  206. )
  207. const parents = getParents(list, self, parentWhere)
  208. const me = list.find((item: any) => selfWhere && selfWhere(item, self))
  209. if (me) {
  210. parents.unshift(me)
  211. }
  212. return parents
  213. }
  214. export default {
  215. toTree: listToTree,
  216. toList: treeToList,
  217. toListWithChildren: treeToListWithChildren,
  218. getParents,
  219. getParentsAndSelf,
  220. }