vxe-pc-ui 3.7.4 → 3.7.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (198) hide show
  1. package/es/icon/style.css +1 -1
  2. package/es/language/ar-EG.js +19 -1
  3. package/es/language/de-DE.js +19 -1
  4. package/es/language/en-US.js +20 -2
  5. package/es/language/es-ES.js +19 -1
  6. package/es/language/fr-FR.js +19 -1
  7. package/es/language/hu-HU.js +19 -1
  8. package/es/language/hy-AM.js +18 -0
  9. package/es/language/id-ID.js +19 -1
  10. package/es/language/it-IT.js +19 -1
  11. package/es/language/ja-JP.js +19 -1
  12. package/es/language/ko-KR.js +19 -1
  13. package/es/language/ms-MY.js +19 -1
  14. package/es/language/nb-NO.js +19 -1
  15. package/es/language/pt-BR.js +19 -1
  16. package/es/language/ru-RU.js +19 -1
  17. package/es/language/th-TH.js +19 -1
  18. package/es/language/ug-CN.js +19 -1
  19. package/es/language/uk-UA.js +19 -1
  20. package/es/language/uz-UZ.js +19 -1
  21. package/es/language/vi-VN.js +19 -1
  22. package/es/language/zh-CHT.js +19 -1
  23. package/es/language/zh-CN.js +18 -0
  24. package/es/list/src/list.js +1 -1
  25. package/es/select/src/select.js +138 -41
  26. package/es/select/style.css +21 -0
  27. package/es/select/style.min.css +1 -1
  28. package/es/style.css +1 -1
  29. package/es/style.min.css +1 -1
  30. package/es/tree/src/tree.js +1160 -601
  31. package/es/tree/src/util.js +31 -0
  32. package/es/tree/style.css +23 -26
  33. package/es/tree/style.min.css +1 -1
  34. package/es/tree-select/src/tree-select.js +258 -24
  35. package/es/tree-select/style.css +36 -1
  36. package/es/tree-select/style.min.css +1 -1
  37. package/es/ui/index.js +20 -4
  38. package/es/ui/src/dom.js +9 -0
  39. package/es/ui/src/log.js +1 -1
  40. package/es/vxe-select/style.css +21 -0
  41. package/es/vxe-select/style.min.css +1 -1
  42. package/es/vxe-tree/style.css +23 -26
  43. package/es/vxe-tree/style.min.css +1 -1
  44. package/es/vxe-tree-select/style.css +36 -1
  45. package/es/vxe-tree-select/style.min.css +1 -1
  46. package/lib/icon/style/style.css +1 -1
  47. package/lib/icon/style/style.min.css +1 -1
  48. package/lib/index.umd.js +1541 -532
  49. package/lib/index.umd.min.js +1 -1
  50. package/lib/language/ar-EG.js +19 -1
  51. package/lib/language/ar-EG.min.js +1 -1
  52. package/lib/language/ar-EG.umd.js +19 -1
  53. package/lib/language/de-DE.js +19 -1
  54. package/lib/language/de-DE.min.js +1 -1
  55. package/lib/language/de-DE.umd.js +19 -1
  56. package/lib/language/en-US.js +20 -2
  57. package/lib/language/en-US.min.js +1 -1
  58. package/lib/language/en-US.umd.js +20 -2
  59. package/lib/language/es-ES.js +19 -1
  60. package/lib/language/es-ES.min.js +1 -1
  61. package/lib/language/es-ES.umd.js +19 -1
  62. package/lib/language/fr-FR.js +19 -1
  63. package/lib/language/fr-FR.min.js +1 -1
  64. package/lib/language/fr-FR.umd.js +19 -1
  65. package/lib/language/hu-HU.js +19 -1
  66. package/lib/language/hu-HU.min.js +1 -1
  67. package/lib/language/hu-HU.umd.js +19 -1
  68. package/lib/language/hy-AM.js +18 -0
  69. package/lib/language/hy-AM.min.js +1 -1
  70. package/lib/language/hy-AM.umd.js +18 -0
  71. package/lib/language/id-ID.js +19 -1
  72. package/lib/language/id-ID.min.js +1 -1
  73. package/lib/language/id-ID.umd.js +19 -1
  74. package/lib/language/it-IT.js +19 -1
  75. package/lib/language/it-IT.min.js +1 -1
  76. package/lib/language/it-IT.umd.js +19 -1
  77. package/lib/language/ja-JP.js +19 -1
  78. package/lib/language/ja-JP.min.js +1 -1
  79. package/lib/language/ja-JP.umd.js +19 -1
  80. package/lib/language/ko-KR.js +19 -1
  81. package/lib/language/ko-KR.min.js +1 -1
  82. package/lib/language/ko-KR.umd.js +19 -1
  83. package/lib/language/ms-MY.js +19 -1
  84. package/lib/language/ms-MY.min.js +1 -1
  85. package/lib/language/ms-MY.umd.js +19 -1
  86. package/lib/language/nb-NO.js +19 -1
  87. package/lib/language/nb-NO.min.js +1 -1
  88. package/lib/language/nb-NO.umd.js +19 -1
  89. package/lib/language/pt-BR.js +19 -1
  90. package/lib/language/pt-BR.min.js +1 -1
  91. package/lib/language/pt-BR.umd.js +19 -1
  92. package/lib/language/ru-RU.js +19 -1
  93. package/lib/language/ru-RU.min.js +1 -1
  94. package/lib/language/ru-RU.umd.js +19 -1
  95. package/lib/language/th-TH.js +19 -1
  96. package/lib/language/th-TH.min.js +1 -1
  97. package/lib/language/th-TH.umd.js +19 -1
  98. package/lib/language/ug-CN.js +19 -1
  99. package/lib/language/ug-CN.min.js +1 -1
  100. package/lib/language/ug-CN.umd.js +19 -1
  101. package/lib/language/uk-UA.js +19 -1
  102. package/lib/language/uk-UA.min.js +1 -1
  103. package/lib/language/uk-UA.umd.js +19 -1
  104. package/lib/language/uz-UZ.js +19 -1
  105. package/lib/language/uz-UZ.min.js +1 -1
  106. package/lib/language/uz-UZ.umd.js +19 -1
  107. package/lib/language/vi-VN.js +19 -1
  108. package/lib/language/vi-VN.min.js +1 -1
  109. package/lib/language/vi-VN.umd.js +19 -1
  110. package/lib/language/zh-CHT.js +19 -1
  111. package/lib/language/zh-CHT.min.js +1 -1
  112. package/lib/language/zh-CHT.umd.js +19 -1
  113. package/lib/language/zh-CN.js +18 -0
  114. package/lib/language/zh-CN.min.js +1 -1
  115. package/lib/language/zh-CN.umd.js +18 -0
  116. package/lib/list/src/list.js +1 -1
  117. package/lib/list/src/list.min.js +1 -1
  118. package/lib/select/src/select.js +145 -45
  119. package/lib/select/src/select.min.js +1 -1
  120. package/lib/select/style/style.css +21 -0
  121. package/lib/select/style/style.min.css +1 -1
  122. package/lib/style.css +1 -1
  123. package/lib/style.min.css +1 -1
  124. package/lib/tree/src/tree.js +1223 -626
  125. package/lib/tree/src/tree.min.js +1 -1
  126. package/lib/tree/src/util.js +37 -0
  127. package/lib/tree/src/util.min.js +1 -0
  128. package/lib/tree/style/style.css +23 -26
  129. package/lib/tree/style/style.min.css +1 -1
  130. package/lib/tree-select/src/tree-select.js +265 -26
  131. package/lib/tree-select/src/tree-select.min.js +1 -1
  132. package/lib/tree-select/style/style.css +36 -1
  133. package/lib/tree-select/style/style.min.css +1 -1
  134. package/lib/ui/index.js +20 -4
  135. package/lib/ui/index.min.js +1 -1
  136. package/lib/ui/src/dom.js +10 -0
  137. package/lib/ui/src/dom.min.js +1 -1
  138. package/lib/ui/src/log.js +1 -1
  139. package/lib/ui/src/log.min.js +1 -1
  140. package/lib/vxe-select/style/style.css +21 -0
  141. package/lib/vxe-select/style/style.min.css +1 -1
  142. package/lib/vxe-tree/style/style.css +23 -26
  143. package/lib/vxe-tree/style/style.min.css +1 -1
  144. package/lib/vxe-tree-select/style/style.css +36 -1
  145. package/lib/vxe-tree-select/style/style.min.css +1 -1
  146. package/package.json +1 -1
  147. package/packages/language/ar-EG.ts +19 -1
  148. package/packages/language/de-DE.ts +19 -1
  149. package/packages/language/en-US.ts +20 -2
  150. package/packages/language/es-ES.ts +19 -1
  151. package/packages/language/fr-FR.ts +19 -1
  152. package/packages/language/hu-HU.ts +19 -1
  153. package/packages/language/hy-AM.ts +18 -0
  154. package/packages/language/id-ID.ts +19 -1
  155. package/packages/language/it-IT.ts +19 -1
  156. package/packages/language/ja-JP.ts +19 -1
  157. package/packages/language/ko-KR.ts +19 -1
  158. package/packages/language/ms-MY.ts +19 -1
  159. package/packages/language/nb-NO.ts +19 -1
  160. package/packages/language/pt-BR.ts +19 -1
  161. package/packages/language/ru-RU.ts +19 -1
  162. package/packages/language/th-TH.ts +19 -1
  163. package/packages/language/ug-CN.ts +19 -1
  164. package/packages/language/uk-UA.ts +19 -1
  165. package/packages/language/uz-UZ.ts +19 -1
  166. package/packages/language/vi-VN.ts +19 -1
  167. package/packages/language/zh-CHT.ts +19 -1
  168. package/packages/language/zh-CN.ts +18 -0
  169. package/packages/list/src/list.ts +1 -1
  170. package/packages/select/src/select.ts +144 -44
  171. package/packages/tree/src/tree.ts +1206 -626
  172. package/packages/tree/src/util.ts +34 -0
  173. package/packages/tree-select/src/tree-select.ts +272 -26
  174. package/packages/ui/index.ts +19 -3
  175. package/packages/ui/src/dom.ts +10 -0
  176. package/styles/components/select.scss +19 -0
  177. package/styles/components/tree-select.scss +36 -1
  178. package/styles/components/tree.scss +28 -31
  179. package/types/components/button.d.ts +11 -1
  180. package/types/components/grid.d.ts +5 -0
  181. package/types/components/icon-picker.d.ts +11 -1
  182. package/types/components/input.d.ts +2 -2
  183. package/types/components/select.d.ts +29 -40
  184. package/types/components/table.d.ts +2 -4
  185. package/types/components/tree-select.d.ts +72 -12
  186. package/types/components/tree.d.ts +129 -8
  187. /package/es/icon/{iconfont.1752133985860.ttf → iconfont.1752416451473.ttf} +0 -0
  188. /package/es/icon/{iconfont.1752133985860.woff → iconfont.1752416451473.woff} +0 -0
  189. /package/es/icon/{iconfont.1752133985860.woff2 → iconfont.1752416451473.woff2} +0 -0
  190. /package/es/{iconfont.1752133985860.ttf → iconfont.1752416451473.ttf} +0 -0
  191. /package/es/{iconfont.1752133985860.woff → iconfont.1752416451473.woff} +0 -0
  192. /package/es/{iconfont.1752133985860.woff2 → iconfont.1752416451473.woff2} +0 -0
  193. /package/lib/icon/style/{iconfont.1752133985860.ttf → iconfont.1752416451473.ttf} +0 -0
  194. /package/lib/icon/style/{iconfont.1752133985860.woff → iconfont.1752416451473.woff} +0 -0
  195. /package/lib/icon/style/{iconfont.1752133985860.woff2 → iconfont.1752416451473.woff2} +0 -0
  196. /package/lib/{iconfont.1752133985860.ttf → iconfont.1752416451473.ttf} +0 -0
  197. /package/lib/{iconfont.1752133985860.woff → iconfont.1752416451473.woff} +0 -0
  198. /package/lib/{iconfont.1752133985860.woff2 → iconfont.1752416451473.woff2} +0 -0
@@ -1,9 +1,11 @@
1
1
  import { PropType, CreateElement, VNode } from 'vue'
2
2
  import { defineVxeComponent } from '../../ui/src/comp'
3
3
  import XEUtils from 'xe-utils'
4
- import { createEvent, getIcon, getConfig, renderEmptyElement, globalMixins } from '../../ui'
4
+ import { getI18n, createEvent, getIcon, getConfig, globalEvents, globalResize, renderEmptyElement, globalMixins } from '../../ui'
5
+ import { calcTreeLine } from './util'
6
+ import { errLog } from '../../ui/src/log'
5
7
  import { getSlotVNs } from '../../ui/src/vn'
6
- import { toCssUnit } from '../../ui/src/dom'
8
+ import { toCssUnit, isScale, getPaddingTopBottomSize } from '../../ui/src/dom'
7
9
  import VxeLoadingComponent from '../../loading/src/loading'
8
10
 
9
11
  import type { TreeReactData, VxeTreeEmits, VxeTreePropTypes, TreeInternalData, VxeTreeDefines, VxeComponentSizeType, ValueOf } from '../../../types'
@@ -34,7 +36,15 @@ export default /* define-vxe-component start */ defineVxeComponent({
34
36
  ],
35
37
  props: {
36
38
  data: Array as PropType<VxeTreePropTypes.Data>,
39
+ autoResize: {
40
+ type: Boolean as PropType<VxeTreePropTypes.AutoResize>,
41
+ default: () => getConfig().tree.autoResize
42
+ },
37
43
  height: [String, Number] as PropType<VxeTreePropTypes.Height>,
44
+ maxHeight: {
45
+ type: [String, Number] as PropType<VxeTreePropTypes.MaxHeight>,
46
+ default: () => getConfig().tree.maxHeight
47
+ },
38
48
  minHeight: {
39
49
  type: [String, Number] as PropType<VxeTreePropTypes.MinHeight>,
40
50
  default: () => getConfig().tree.minHeight
@@ -126,15 +136,25 @@ export default /* define-vxe-component start */ defineVxeComponent({
126
136
  type: String as PropType<VxeTreePropTypes.IconLoaded>,
127
137
  default: () => getConfig().tree.iconLoaded
128
138
  },
139
+ filterValue: [String, Number] as PropType<VxeTreePropTypes.FilterValue>,
140
+ filterConfig: Object as PropType<VxeTreePropTypes.FilterConfig>,
129
141
  size: {
130
142
  type: String as PropType<VxeTreePropTypes.Size>,
131
143
  default: () => getConfig().tree.size || getConfig().size
132
- }
144
+ },
145
+ virtualYConfig: Object as PropType<VxeTreePropTypes.VirtualYConfig>
133
146
  },
134
147
  data () {
135
148
  const xID = XEUtils.uniqueId()
136
149
  const reactData: TreeReactData = {
150
+ parentHeight: 0,
151
+ customHeight: 0,
152
+ customMinHeight: 0,
153
+ customMaxHeight: 0,
137
154
  currentNode: null,
155
+ scrollYLoad: false,
156
+ bodyHeight: 0,
157
+ topSpaceHeight: 0,
138
158
  selectRadioKey: null,
139
159
  treeList: [],
140
160
  updateExpandedFlag: 1,
@@ -142,11 +162,28 @@ export default /* define-vxe-component start */ defineVxeComponent({
142
162
  }
143
163
  const internalData: TreeInternalData = {
144
164
  // initialized: false,
165
+ // lastFilterValue: '',
166
+ treeFullData: [],
167
+ afterTreeList: [],
168
+ afterVisibleList: [],
145
169
  nodeMaps: {},
146
170
  selectCheckboxMaps: {},
147
171
  indeterminateRowMaps: {},
148
172
  treeExpandedMaps: {},
149
- treeExpandLazyLoadedMaps: {}
173
+ treeExpandLazyLoadedMaps: {},
174
+
175
+ lastScrollLeft: 0,
176
+ lastScrollTop: 0,
177
+ scrollYStore: {
178
+ startIndex: 0,
179
+ endIndex: 0,
180
+ visibleSize: 0,
181
+ offsetSize: 0,
182
+ rowHeight: 0
183
+ },
184
+
185
+ lastScrollTime: 0
186
+ // hpTimeout: undefined
150
187
  }
151
188
  return {
152
189
  xID,
@@ -201,6 +238,12 @@ export default /* define-vxe-component start */ defineVxeComponent({
201
238
 
202
239
  return props.hasChildField || 'hasChild'
203
240
  },
241
+ computeVirtualYOpts () {
242
+ const $xeTree = this
243
+ const props = $xeTree
244
+
245
+ return Object.assign({} as { gt: number }, getConfig().tree.virtualYConfig, props.virtualYConfig)
246
+ },
204
247
  computeIsRowCurrent () {
205
248
  const $xeTree = this
206
249
  const props = $xeTree
@@ -249,17 +292,26 @@ export default /* define-vxe-component start */ defineVxeComponent({
249
292
  },
250
293
  computeTreeStyle () {
251
294
  const $xeTree = this
252
- const props = $xeTree
295
+ const reactData = $xeTree.reactData
253
296
 
254
- const { height, minHeight } = props
297
+ const { customHeight, customMinHeight, customMaxHeight } = reactData
255
298
  const stys: Record<string, string> = {}
256
- if (height) {
257
- stys.height = toCssUnit(height)
299
+ if (customHeight) {
300
+ stys.height = toCssUnit(customHeight)
258
301
  }
259
- if (minHeight) {
260
- stys.minHeight = toCssUnit(minHeight)
302
+ if (customMinHeight) {
303
+ stys.minHeight = toCssUnit(customMinHeight)
304
+ }
305
+ if (customMaxHeight) {
306
+ stys.maxHeight = toCssUnit(customMaxHeight)
261
307
  }
262
308
  return stys
309
+ },
310
+ computeFilterOpts () {
311
+ const $xeTree = this
312
+ const props = $xeTree
313
+
314
+ return Object.assign({}, getConfig().tree.filterConfig, props.filterConfig)
263
315
  }
264
316
  },
265
317
  methods: {
@@ -270,614 +322,646 @@ export default /* define-vxe-component start */ defineVxeComponent({
270
322
  const $xeTree = this
271
323
  $xeTree.$emit(type, createEvent(evnt, { $tree: $xeTree }, params))
272
324
  },
273
- clearCurrentNode () {
325
+ getNodeId (node: any) {
274
326
  const $xeTree = this
275
- const reactData = $xeTree.reactData
276
327
 
277
- reactData.currentNode = null
278
- return $xeTree.$nextTick()
328
+ const valueField = $xeTree.computeValueField
329
+ const nodeid = XEUtils.get(node, valueField)
330
+ return XEUtils.eqNull(nodeid) ? '' : encodeURIComponent(nodeid)
279
331
  },
280
- getCurrentNodeId () {
332
+ isExpandByNode (node: any) {
281
333
  const $xeTree = this
282
334
  const reactData = $xeTree.reactData
335
+ const internalData = $xeTree.internalData
283
336
 
284
- const { currentNode } = reactData
285
- if (currentNode) {
286
- return $xeTree.getNodeId(currentNode)
287
- }
288
- return null
337
+ const { updateExpandedFlag } = reactData
338
+ const { treeExpandedMaps } = internalData
339
+ const nodeid = $xeTree.getNodeId(node)
340
+ return !!(updateExpandedFlag && treeExpandedMaps[nodeid])
289
341
  },
290
- getCurrentNode () {
342
+ isCheckedByRadioNodeId (nodeid: any) {
291
343
  const $xeTree = this
292
344
  const reactData = $xeTree.reactData
293
- const internalData = $xeTree.internalData
294
345
 
295
- const { currentNode } = reactData
296
- const { nodeMaps } = internalData
297
- if (currentNode) {
298
- const nodeItem = nodeMaps[$xeTree.getNodeId(currentNode)]
299
- if (nodeItem) {
300
- return nodeItem.item
301
- }
302
- }
303
- return null
346
+ const { selectRadioKey } = reactData
347
+ return selectRadioKey === nodeid
304
348
  },
305
- setCurrentNodeId (nodeKey: any) {
349
+ isCheckedByRadioNode (node: any) {
350
+ const $xeTree = this
351
+
352
+ return $xeTree.isCheckedByRadioNodeId($xeTree.getNodeId(node))
353
+ },
354
+ isCheckedByCheckboxNodeId (nodeid: any) {
306
355
  const $xeTree = this
307
356
  const reactData = $xeTree.reactData
308
357
  const internalData = $xeTree.internalData
309
358
 
310
- const { nodeMaps } = internalData
311
- const nodeItem = nodeMaps[nodeKey]
312
- reactData.currentNode = nodeItem ? nodeItem.item : null
313
- return $xeTree.$nextTick()
359
+ const { updateCheckboxFlag } = reactData
360
+ const { selectCheckboxMaps } = internalData
361
+ return !!(updateCheckboxFlag && selectCheckboxMaps[nodeid])
314
362
  },
315
- setCurrentNode (node: any) {
363
+ isCheckedByCheckboxNode (node: any) {
316
364
  const $xeTree = this
317
- const reactData = $xeTree.reactData
318
365
 
319
- reactData.currentNode = node
320
- return $xeTree.$nextTick()
366
+ return $xeTree.isCheckedByCheckboxNodeId($xeTree.getNodeId(node))
321
367
  },
322
- clearRadioNode () {
368
+ isIndeterminateByCheckboxNodeid (nodeid: any) {
323
369
  const $xeTree = this
324
370
  const reactData = $xeTree.reactData
371
+ const internalData = $xeTree.internalData
325
372
 
326
- reactData.selectRadioKey = null
327
- return $xeTree.$nextTick()
373
+ const { updateCheckboxFlag } = reactData
374
+ const { indeterminateRowMaps } = internalData
375
+ return !!(updateCheckboxFlag && indeterminateRowMaps[nodeid])
328
376
  },
329
- getCheckboxNodeIds () {
377
+ isIndeterminateByCheckboxNode (node: any) {
330
378
  const $xeTree = this
331
- const internalData = $xeTree.internalData
332
379
 
333
- const { selectCheckboxMaps } = internalData
334
- return Object.keys(selectCheckboxMaps)
380
+ return $xeTree.isIndeterminateByCheckboxNodeid($xeTree.getNodeId(node))
335
381
  },
336
- getCheckboxNodes () {
382
+ emitCheckboxMode (value: VxeTreePropTypes.CheckNodeKeys) {
337
383
  const $xeTree = this
338
- const internalData = $xeTree.internalData
339
384
 
340
- const { nodeMaps, selectCheckboxMaps } = internalData
341
- const list: any[] = []
342
- XEUtils.each(selectCheckboxMaps, (item, nodeid) => {
343
- const nodeItem = nodeMaps[nodeid]
344
- if (nodeItem) {
345
- list.push(nodeItem.item)
346
- }
347
- })
348
- return list
385
+ $xeTree.$emit('update:checkNodeKeys', value)
349
386
  },
350
- clearCheckboxNode () {
387
+ emitRadioMode (value: VxeTreePropTypes.CheckNodeKey) {
351
388
  const $xeTree = this
352
- const reactData = $xeTree.reactData
353
- const internalData = $xeTree.internalData
354
389
 
355
- internalData.selectCheckboxMaps = {}
356
- reactData.updateCheckboxFlag++
357
- return $xeTree.$nextTick()
390
+ $xeTree.$emit('update:checkNodeKey', value)
358
391
  },
359
- setAllCheckboxNode (checked: any) {
392
+ setRadioNode (node: any) {
360
393
  const $xeTree = this
361
- const props = $xeTree
362
394
  const reactData = $xeTree.reactData
363
- const internalData = $xeTree.internalData
364
395
 
365
- const { transform } = props
366
- const selectMaps: Record<string, boolean> = {}
367
- const childrenField = $xeTree.computeChildrenField
368
- const mapChildrenField = $xeTree.computeMapChildrenField
369
- if (checked) {
370
- XEUtils.eachTree(reactData.treeList, (node) => {
371
- const nodeid = $xeTree.getNodeId(node)
372
- selectMaps[nodeid] = true
373
- }, { children: transform ? mapChildrenField : childrenField })
396
+ if (node) {
397
+ reactData.selectRadioKey = $xeTree.getNodeId(node)
374
398
  }
375
- internalData.selectCheckboxMaps = selectMaps
376
- reactData.updateCheckboxFlag++
377
399
  return $xeTree.$nextTick()
378
400
  },
379
- clearExpandNode () {
401
+ setCheckboxNode (nodeList: any | any[], checked: boolean) {
380
402
  const $xeTree = this
381
403
 
382
- return $xeTree.clearAllExpandNode()
404
+ if (nodeList) {
405
+ if (!XEUtils.isArray(nodeList)) {
406
+ nodeList = [nodeList]
407
+ }
408
+ $xeTree.handleCheckedCheckboxNode(nodeList, checked)
409
+ }
410
+ return $xeTree.$nextTick()
383
411
  },
384
- clearAllExpandNode () {
412
+ setCheckboxByNodeId (nodeIds: any | any[], checked: boolean) {
385
413
  const $xeTree = this
386
- const reactData = $xeTree.reactData
387
414
  const internalData = $xeTree.internalData
388
415
 
389
416
  const { nodeMaps } = internalData
390
- XEUtils.each(nodeMaps, (nodeItem: VxeTreeDefines.NodeCacheItem) => {
391
- nodeItem.treeLoaded = false
392
- })
393
- internalData.treeExpandedMaps = {}
394
- reactData.updateExpandedFlag++
417
+ if (nodeIds) {
418
+ if (!XEUtils.isArray(nodeIds)) {
419
+ nodeIds = [nodeIds]
420
+ }
421
+ const nodeList: any[] = []
422
+ nodeIds.forEach((nodeid: string) => {
423
+ const nodeItem = nodeMaps[nodeid]
424
+ if (nodeItem) {
425
+ nodeList.push(nodeItem.item)
426
+ }
427
+ })
428
+ $xeTree.handleCheckedCheckboxNode(nodeList, checked)
429
+ }
395
430
  return $xeTree.$nextTick()
396
431
  },
397
- setExpandByNodeId (nodeids: any, expanded: any) {
432
+ handleCheckedCheckboxNode (nodeList: any[], checked: boolean) {
398
433
  const $xeTree = this
434
+ const props = $xeTree
399
435
  const reactData = $xeTree.reactData
400
436
  const internalData = $xeTree.internalData
401
437
 
402
- const { treeExpandedMaps } = internalData
403
- if (nodeids) {
404
- if (!XEUtils.isArray(nodeids)) {
405
- nodeids = [nodeids]
438
+ const { transform } = props
439
+ const { selectCheckboxMaps } = internalData
440
+ const mapChildrenField = $xeTree.computeMapChildrenField
441
+ const childrenField = $xeTree.computeChildrenField
442
+ const checkboxOpts = $xeTree.computeCheckboxOpts
443
+ const { checkStrictly } = checkboxOpts
444
+ const handleSelect = (node: any) => {
445
+ const nodeid = $xeTree.getNodeId(node)
446
+ if (checked) {
447
+ if (!selectCheckboxMaps[nodeid]) {
448
+ selectCheckboxMaps[nodeid] = node
449
+ }
450
+ } else {
451
+ if (selectCheckboxMaps[nodeid]) {
452
+ delete selectCheckboxMaps[nodeid]
453
+ }
406
454
  }
407
- nodeids.forEach((nodeid: string) => {
408
- handleSetExpand(nodeid, expanded, treeExpandedMaps)
409
- })
410
- reactData.updateExpandedFlag++
411
455
  }
412
- return $xeTree.$nextTick()
456
+ if (checkStrictly) {
457
+ nodeList.forEach(handleSelect)
458
+ } else {
459
+ XEUtils.eachTree(nodeList, handleSelect, { children: transform ? mapChildrenField : childrenField })
460
+ }
461
+ reactData.updateCheckboxFlag++
462
+ $xeTree.updateCheckboxStatus()
413
463
  },
414
- getExpandNodeIds () {
464
+ updateCheckboxChecked (nodeIds: VxeTreePropTypes.CheckNodeKeys) {
415
465
  const $xeTree = this
416
- const internalData = $xeTree.internalData
417
466
 
418
- const { treeExpandedMaps } = internalData
419
- return XEUtils.keys(treeExpandedMaps)
467
+ $xeTree.setCheckboxByNodeId(nodeIds, true)
420
468
  },
421
- getExpandNodes () {
469
+ handleSetExpand (nodeid: string, expanded: boolean, expandedMaps: Record<string, boolean>) {
470
+ if (expanded) {
471
+ if (!expandedMaps[nodeid]) {
472
+ expandedMaps[nodeid] = true
473
+ }
474
+ } else {
475
+ if (expandedMaps[nodeid]) {
476
+ delete expandedMaps[nodeid]
477
+ }
478
+ }
479
+ },
480
+ getParentElem () {
422
481
  const $xeTree = this
423
- const internalData = $xeTree.internalData
424
482
 
425
- const { nodeMaps, treeExpandedMaps } = internalData
426
- const list: any[] = []
427
- XEUtils.each(treeExpandedMaps, (item, nodeid) => {
428
- const nodeItem = nodeMaps[nodeid]
429
- if (nodeItem) {
430
- list.push(nodeItem.item)
431
- }
432
- })
433
- return list
483
+ const el = $xeTree.$refs.refElem as HTMLDivElement
484
+ return el ? el.parentElement : null
434
485
  },
435
- setExpandNode (nodes: any, expanded: any) {
486
+ calcTableHeight (key: 'height' | 'minHeight' | 'maxHeight') {
436
487
  const $xeTree = this
488
+ const props = $xeTree
437
489
  const reactData = $xeTree.reactData
438
- const internalData = $xeTree.internalData
439
490
 
440
- const { treeExpandedMaps } = internalData
441
- if (nodes) {
442
- if (!XEUtils.isArray(nodes)) {
443
- nodes = [nodes]
491
+ const { parentHeight } = reactData
492
+ const val = props[key]
493
+ let num = 0
494
+ if (val) {
495
+ if (val === '100%' || val === 'auto') {
496
+ num = parentHeight
497
+ } else {
498
+ if (isScale(val)) {
499
+ num = Math.floor((XEUtils.toInteger(val) || 1) / 100 * parentHeight)
500
+ } else {
501
+ num = XEUtils.toNumber(val)
502
+ }
503
+ num = Math.max(40, num)
444
504
  }
445
- nodes.forEach((node: any) => {
446
- const nodeid = $xeTree.getNodeId(node)
447
- handleSetExpand(nodeid, expanded, treeExpandedMaps)
448
- })
449
- reactData.updateExpandedFlag++
450
505
  }
451
- return $xeTree.$nextTick()
506
+ return num
452
507
  },
453
- toggleExpandByNodeId (nodeids: any) {
508
+ updateHeight () {
454
509
  const $xeTree = this
455
510
  const reactData = $xeTree.reactData
456
- const internalData = $xeTree.internalData
457
511
 
458
- const { treeExpandedMaps } = internalData
459
- if (nodeids) {
460
- if (!XEUtils.isArray(nodeids)) {
461
- nodeids = [nodeids]
462
- }
463
- nodeids.forEach((nodeid: string) => {
464
- handleSetExpand(nodeid, !treeExpandedMaps[nodeid], treeExpandedMaps)
465
- })
466
- reactData.updateExpandedFlag++
512
+ reactData.customHeight = $xeTree.calcTableHeight('height')
513
+ reactData.customMinHeight = $xeTree.calcTableHeight('minHeight')
514
+ reactData.customMaxHeight = $xeTree.calcTableHeight('maxHeight')
515
+
516
+ // 如果启用虚拟滚动,默认高度
517
+ if (reactData.scrollYLoad && !(reactData.customHeight || reactData.customMinHeight)) {
518
+ reactData.customHeight = 300
467
519
  }
468
- return $xeTree.$nextTick()
469
520
  },
470
- toggleExpandNode (nodes: any) {
521
+ createNode (records: any[]) {
471
522
  const $xeTree = this
472
- const reactData = $xeTree.reactData
473
- const internalData = $xeTree.internalData
474
523
 
475
- const { treeExpandedMaps } = internalData
476
- if (nodes) {
477
- if (!XEUtils.isArray(nodes)) {
478
- nodes = [nodes]
479
- }
480
- nodes.forEach((node: any) => {
481
- const nodeid = $xeTree.getNodeId(node)
482
- handleSetExpand(nodeid, !treeExpandedMaps[nodeid], treeExpandedMaps)
524
+ const valueField = $xeTree.computeValueField
525
+ return Promise.resolve(
526
+ records.map(obj => {
527
+ const item = { ...obj }
528
+ let nodeid = $xeTree.getNodeId(item)
529
+ if (!nodeid) {
530
+ nodeid = getNodeUniqueId()
531
+ XEUtils.set(item, valueField, nodeid)
532
+ }
533
+ return item
483
534
  })
484
- reactData.updateExpandedFlag++
485
- }
486
- return $xeTree.$nextTick()
535
+ )
487
536
  },
488
- setAllExpandNode (expanded: boolean) {
537
+ cacheNodeMap () {
489
538
  const $xeTree = this
490
- const props = $xeTree
491
- const reactData = $xeTree.reactData
492
539
  const internalData = $xeTree.internalData
493
540
 
494
- const { transform } = props
495
- const { treeExpandedMaps } = internalData
541
+ const { treeFullData } = internalData
542
+ const valueField = $xeTree.computeValueField
496
543
  const childrenField = $xeTree.computeChildrenField
497
- const mapChildrenField = $xeTree.computeMapChildrenField
498
- if (expanded) {
499
- XEUtils.eachTree(reactData.treeList, (node) => {
500
- const childList: any[] = XEUtils.get(node, childrenField)
501
- const hasChild = childList && childList.length
502
- if (hasChild) {
503
- const nodeid = $xeTree.getNodeId(node)
504
- treeExpandedMaps[nodeid] = true
505
- }
506
- }, { children: transform ? mapChildrenField : childrenField })
507
- } else {
508
- internalData.treeExpandedMaps = {}
509
- }
510
- reactData.updateExpandedFlag++
511
- return $xeTree.$nextTick()
512
- },
513
- reloadExpandNode (node: any) {
514
- const $xeTree = this
515
- const props = $xeTree
516
-
517
- const { lazy } = props
518
- if (lazy) {
519
- $xeTree.clearExpandLoaded(node)
520
- return $xeTree.handleAsyncTreeExpandChilds(node)
521
- }
522
- return $xeTree.$nextTick()
544
+ const keyMaps: Record<string, VxeTreeDefines.NodeCacheItem> = {}
545
+ XEUtils.eachTree(treeFullData, (item, index, items, path, parent, nodes) => {
546
+ let nodeid = $xeTree.getNodeId(item)
547
+ if (!nodeid) {
548
+ nodeid = getNodeUniqueId()
549
+ XEUtils.set(item, valueField, nodeid)
550
+ }
551
+ keyMaps[nodeid] = {
552
+ item,
553
+ index,
554
+ items,
555
+ parent,
556
+ nodes,
557
+ level: nodes.length,
558
+ treeIndex: index,
559
+ lineCount: 0,
560
+ treeLoaded: false
561
+ }
562
+ }, { children: childrenField })
563
+ internalData.nodeMaps = keyMaps
523
564
  },
524
- clearExpandLoaded (node: any) {
565
+ updateAfterDataIndex () {
525
566
  const $xeTree = this
526
567
  const props = $xeTree
527
568
  const internalData = $xeTree.internalData
528
569
 
529
- const { lazy } = props
530
- const { nodeMaps } = internalData
531
- if (lazy) {
532
- const nodeItem = nodeMaps[$xeTree.getNodeId(node)]
570
+ const { transform } = props
571
+ const { afterTreeList, nodeMaps } = internalData
572
+ const childrenField = $xeTree.computeChildrenField
573
+ const mapChildrenField = $xeTree.computeMapChildrenField
574
+ XEUtils.eachTree(afterTreeList, (item, index, items) => {
575
+ const nodeid = $xeTree.getNodeId(item)
576
+ const nodeItem = nodeMaps[nodeid]
533
577
  if (nodeItem) {
534
- nodeItem.treeLoaded = false
578
+ nodeItem.items = items
579
+ nodeItem.treeIndex = index
580
+ } else {
581
+ const rest = {
582
+ item,
583
+ index,
584
+ items,
585
+ parent,
586
+ nodes: [],
587
+ level: 0,
588
+ treeIndex: index,
589
+ lineCount: 0,
590
+ treeLoaded: false
591
+ }
592
+ nodeMaps[nodeid] = rest
535
593
  }
536
- }
537
- return $xeTree.$nextTick()
594
+ }, { children: transform ? mapChildrenField : childrenField })
538
595
  },
539
- /**
540
- * 用于树结构,给行数据加载子节点
541
- */
542
- loadChildrenNode (node: any, childRecords: any) {
596
+ updateAfterFullData () {
543
597
  const $xeTree = this
544
598
  const props = $xeTree
545
599
  const internalData = $xeTree.internalData
546
600
 
547
- const { lazy, transform } = props
548
- const { nodeMaps } = internalData
549
- if (!lazy) {
550
- return Promise.resolve([])
551
- }
601
+ const { transform, filterValue } = props
602
+ const { treeFullData, lastFilterValue } = internalData
603
+ const titleField = $xeTree.computeTitleField
552
604
  const childrenField = $xeTree.computeChildrenField
553
- const parentNodeItem = nodeMaps[$xeTree.getNodeId(node)]
554
- const parentLevel = parentNodeItem ? parentNodeItem.level : 0
555
- const parentNodes = parentNodeItem ? parentNodeItem.nodes : []
556
- return $xeTree.createNode(childRecords).then((nodeList) => {
557
- XEUtils.eachTree(nodeList, (childRow, index, items, path, parent, nodes) => {
558
- const itemNodeId = $xeTree.getNodeId(childRow)
559
- nodeMaps[itemNodeId] = {
560
- item: node,
561
- itemIndex: -1,
562
- items,
563
- parent: parent || parentNodeItem.item,
564
- nodes: parentNodes.concat(nodes),
565
- level: parentLevel + nodes.length,
566
- lineCount: 0,
567
- treeLoaded: false
605
+ const mapChildrenField = $xeTree.computeMapChildrenField
606
+ const filterOpts = $xeTree.computeFilterOpts
607
+ const { autoExpandAll, beforeFilterMethod, filterMethod, afterFilterMethod } = filterOpts
608
+ let fullList = treeFullData
609
+ let treeList = fullList
610
+ let filterStr = ''
611
+ if (filterValue || filterValue === 0) {
612
+ filterStr = `${filterValue}`
613
+ const handleSearch = filterMethod
614
+ ? (item: any) => {
615
+ return filterMethod({
616
+ $tree: $xeTree,
617
+ node: item,
618
+ filterValue: filterStr
619
+ })
620
+ }
621
+ : (item: any) => {
622
+ return String(item[titleField]).toLowerCase().indexOf(filterStr) > -1
623
+ }
624
+ const bafParams = { $tree: $xeTree, filterValue: filterStr }
625
+ if (beforeFilterMethod) {
626
+ beforeFilterMethod(bafParams)
627
+ }
628
+ if (transform) {
629
+ treeList = XEUtils.searchTree(treeFullData, handleSearch, { children: childrenField, mapChildren: mapChildrenField, isEvery: true })
630
+ fullList = treeList
631
+ } else {
632
+ fullList = treeFullData.filter(handleSearch)
633
+ }
634
+ internalData.lastFilterValue = filterStr
635
+ $xeTree.$nextTick(() => {
636
+ // 筛选时自动展开
637
+ if (autoExpandAll) {
638
+ $xeTree.setAllExpandNode(true).then(() => {
639
+ if (afterFilterMethod) {
640
+ afterFilterMethod(bafParams)
641
+ }
642
+ })
643
+ } else {
644
+ if (afterFilterMethod) {
645
+ afterFilterMethod(bafParams)
646
+ }
568
647
  }
569
- }, { children: childrenField })
570
- node[childrenField] = nodeList
648
+ })
649
+ } else {
571
650
  if (transform) {
572
- node[childrenField] = nodeList
651
+ treeList = XEUtils.searchTree(treeFullData, () => true, { children: childrenField, mapChildren: mapChildrenField, isEvery: true })
652
+ fullList = treeList
653
+ if (lastFilterValue) {
654
+ const bafParams = { $tree: $xeTree, filterValue: filterStr }
655
+ if (beforeFilterMethod) {
656
+ beforeFilterMethod(bafParams)
657
+ }
658
+ // 取消筛选时自动收起
659
+ $xeTree.$nextTick(() => {
660
+ if (autoExpandAll) {
661
+ $xeTree.clearAllExpandNode().then(() => {
662
+ if (afterFilterMethod) {
663
+ afterFilterMethod(bafParams)
664
+ }
665
+ })
666
+ } else {
667
+ if (afterFilterMethod) {
668
+ afterFilterMethod(bafParams)
669
+ }
670
+ }
671
+ })
672
+ }
573
673
  }
574
- $xeTree.updateNodeLine(node)
575
- return nodeList
576
- })
674
+ internalData.lastFilterValue = ''
675
+ }
676
+ internalData.afterVisibleList = fullList
677
+ internalData.afterTreeList = treeList
678
+ $xeTree.updateAfterDataIndex()
577
679
  },
578
- getNodeId (node: any) {
680
+ /**
681
+ * 如果为虚拟树、则将树结构拍平
682
+ */
683
+ handleTreeToList () {
579
684
  const $xeTree = this
685
+ const props = $xeTree
686
+ const internalData = $xeTree.internalData
580
687
 
581
- const valueField = $xeTree.computeValueField
582
- const nodeid = XEUtils.get(node, valueField)
583
- return XEUtils.eqNull(nodeid) ? '' : encodeURIComponent(nodeid)
688
+ const { transform } = props
689
+ const { afterTreeList, treeExpandedMaps } = internalData
690
+ const mapChildrenField = $xeTree.computeMapChildrenField
691
+ const expandMaps: {
692
+ [key: string]: number
693
+ } = {}
694
+ if (transform) {
695
+ const fullData: any[] = []
696
+ XEUtils.eachTree(afterTreeList, (item, index, items, path, parentRow) => {
697
+ const nodeid = $xeTree.getNodeId(item)
698
+ const parentNodeid = $xeTree.getNodeId(parentRow)
699
+ if (!parentRow || (expandMaps[parentNodeid] && treeExpandedMaps[parentNodeid])) {
700
+ expandMaps[nodeid] = 1
701
+ fullData.push(item)
702
+ }
703
+ }, { children: mapChildrenField })
704
+ $xeTree.updateScrollYStatus(fullData)
705
+ internalData.afterVisibleList = fullData
706
+ return fullData
707
+ }
708
+ return internalData.afterVisibleList
584
709
  },
585
- isExpandByNode (node: any) {
710
+ handleData (force?: boolean) {
586
711
  const $xeTree = this
587
712
  const reactData = $xeTree.reactData
588
713
  const internalData = $xeTree.internalData
589
714
 
590
- const { updateExpandedFlag } = reactData
591
- const { treeExpandedMaps } = internalData
592
- const nodeid = $xeTree.getNodeId(node)
593
- return !!(updateExpandedFlag && treeExpandedMaps[nodeid])
715
+ const { scrollYLoad } = reactData
716
+ const { scrollYStore } = internalData
717
+ let fullList: any[] = internalData.afterVisibleList
718
+ if (force) {
719
+ // 更新数据,处理筛选和排序
720
+ $xeTree.updateAfterFullData()
721
+ // 如果为虚拟树,将树结构拍平
722
+ fullList = $xeTree.handleTreeToList()
723
+ }
724
+ const treeList = scrollYLoad ? fullList.slice(scrollYStore.startIndex, scrollYStore.endIndex) : fullList.slice(0)
725
+ reactData.treeList = treeList
594
726
  },
595
- isCheckedByRadioNodeId (nodeid: any) {
596
- const $xeTree = this
597
- const reactData = $xeTree.reactData
727
+ triggerSearchEvent: XEUtils.debounce(function (this: any) {
728
+ const $xeSelect = this
598
729
 
599
- const { selectRadioKey } = reactData
600
- return selectRadioKey === nodeid
601
- },
602
- isCheckedByRadioNode (node: any) {
730
+ $xeSelect.handleData(true)
731
+ }, 350, { trailing: true }),
732
+ loadData (list: any[]) {
603
733
  const $xeTree = this
734
+ const props = $xeTree
735
+ const internalData = $xeTree.internalData
604
736
 
605
- return $xeTree.isCheckedByRadioNodeId($xeTree.getNodeId(node))
737
+ const { expandAll, transform } = props
738
+ const { initialized, scrollYStore } = internalData
739
+ const keyField = $xeTree.computeKeyField
740
+ const parentField = $xeTree.computeParentField
741
+ const childrenField = $xeTree.computeChildrenField
742
+ const fullData = transform ? XEUtils.toArrayTree(list, { key: keyField, parentKey: parentField, mapChildren: childrenField }) : list ? list.slice(0) : []
743
+ internalData.treeFullData = fullData
744
+ Object.assign(scrollYStore, {
745
+ startIndex: 0,
746
+ endIndex: 1,
747
+ visibleSize: 0
748
+ })
749
+ const sYLoad = $xeTree.updateScrollYStatus(fullData)
750
+ $xeTree.cacheNodeMap()
751
+ $xeTree.handleData(true)
752
+ if (sYLoad) {
753
+ if (!(props.height || props.maxHeight)) {
754
+ errLog('vxe.error.reqProp', ['height | max-height | virtual-y-config.enabled=false'])
755
+ }
756
+ }
757
+ return $xeTree.computeScrollLoad().then(() => {
758
+ if (!initialized) {
759
+ if (list && list.length) {
760
+ internalData.initialized = true
761
+ if (expandAll) {
762
+ $xeTree.setAllExpandNode(true)
763
+ }
764
+ $xeTree.setCheckboxByNodeId(props.checkNodeKeys || [], true)
765
+ }
766
+ }
767
+ $xeTree.updateHeight()
768
+ $xeTree.refreshScroll()
769
+ })
606
770
  },
607
- isCheckedByCheckboxNodeId (nodeid: any) {
771
+ updateScrollYStatus (fullData?: any[]) {
608
772
  const $xeTree = this
773
+ const props = $xeTree
609
774
  const reactData = $xeTree.reactData
610
775
  const internalData = $xeTree.internalData
611
776
 
612
- const { updateCheckboxFlag } = reactData
613
- const { selectCheckboxMaps } = internalData
614
- return !!(updateCheckboxFlag && selectCheckboxMaps[nodeid])
615
- },
616
- isCheckedByCheckboxNode (node: any) {
617
- const $xeTree = this
618
-
619
- return $xeTree.isCheckedByCheckboxNodeId($xeTree.getNodeId(node))
777
+ const { transform } = props
778
+ const virtualYOpts = $xeTree.computeVirtualYOpts
779
+ const allList = fullData || internalData.treeFullData
780
+ // 如果gt为0,则总是启用
781
+ const scrollYLoad = !!transform && !!virtualYOpts.enabled && virtualYOpts.gt > -1 && (virtualYOpts.gt === 0 || virtualYOpts.gt < allList.length)
782
+ reactData.scrollYLoad = scrollYLoad
783
+ return scrollYLoad
620
784
  },
621
- isIndeterminateByCheckboxNodeid (nodeid: any) {
785
+ updateYSpace () {
622
786
  const $xeTree = this
623
787
  const reactData = $xeTree.reactData
624
788
  const internalData = $xeTree.internalData
625
789
 
626
- const { updateCheckboxFlag } = reactData
627
- const { indeterminateRowMaps } = internalData
628
- return !!(updateCheckboxFlag && indeterminateRowMaps[nodeid])
790
+ const { scrollYLoad } = reactData
791
+ const { scrollYStore, afterVisibleList } = internalData
792
+ reactData.bodyHeight = scrollYLoad ? afterVisibleList.length * scrollYStore.rowHeight : 0
793
+ reactData.topSpaceHeight = scrollYLoad ? Math.max(scrollYStore.startIndex * scrollYStore.rowHeight, 0) : 0
629
794
  },
630
- isIndeterminateByCheckboxNode (node: any) {
795
+ updateYData () {
631
796
  const $xeTree = this
632
797
 
633
- return $xeTree.isIndeterminateByCheckboxNodeid($xeTree.getNodeId(node))
798
+ $xeTree.handleData()
799
+ $xeTree.updateYSpace()
634
800
  },
635
- getCheckboxIndeterminateNodes () {
801
+ computeScrollLoad () {
636
802
  const $xeTree = this
803
+ const reactData = $xeTree.reactData
637
804
  const internalData = $xeTree.internalData
638
805
 
639
- const { nodeMaps, indeterminateRowMaps } = internalData
640
- const list: any[] = []
641
- XEUtils.each(indeterminateRowMaps, (item, nodeid) => {
642
- const nodeItem = nodeMaps[nodeid]
643
- if (nodeItem) {
644
- list.push(nodeItem.item)
806
+ return $xeTree.$nextTick().then(() => {
807
+ const { scrollYLoad } = reactData
808
+ const { scrollYStore } = internalData
809
+ const virtualBodyElem = $xeTree.$refs.refVirtualBody as HTMLDivElement
810
+ const virtualYOpts = $xeTree.computeVirtualYOpts
811
+ let rowHeight = 0
812
+ let firstItemElem: HTMLElement | undefined
813
+ if (virtualBodyElem) {
814
+ if (!firstItemElem) {
815
+ firstItemElem = virtualBodyElem.children[0] as HTMLElement
816
+ }
817
+ }
818
+ if (firstItemElem) {
819
+ rowHeight = firstItemElem.offsetHeight
820
+ }
821
+ rowHeight = Math.max(20, rowHeight)
822
+ scrollYStore.rowHeight = rowHeight
823
+ // 计算 Y 逻辑
824
+ if (scrollYLoad) {
825
+ const scrollBodyElem = $xeTree.$refs.refVirtualWrapper as HTMLDivElement
826
+ const visibleYSize = Math.max(8, scrollBodyElem ? Math.ceil(scrollBodyElem.clientHeight / rowHeight) : 0)
827
+ const offsetYSize = Math.max(0, Math.min(2, XEUtils.toNumber(virtualYOpts.oSize)))
828
+ scrollYStore.offsetSize = offsetYSize
829
+ scrollYStore.visibleSize = visibleYSize
830
+ scrollYStore.endIndex = Math.max(scrollYStore.startIndex, visibleYSize + offsetYSize, scrollYStore.endIndex)
831
+ $xeTree.updateYData()
832
+ } else {
833
+ $xeTree.updateYSpace()
645
834
  }
646
835
  })
647
- return list
648
- },
649
- emitCheckboxMode (value: VxeTreePropTypes.CheckNodeKeys) {
650
- const $xeTree = this
651
-
652
- $xeTree.$emit('update:checkNodeKeys', value)
653
- },
654
- emitRadioMode (value: VxeTreePropTypes.CheckNodeKey) {
655
- const $xeTree = this
656
-
657
- $xeTree.$emit('update:checkNodeKey', value)
658
836
  },
659
- getRadioNodeId () {
837
+ /**
838
+ * 如果有滚动条,则滚动到对应的位置
839
+ * @param {Number} scrollLeft 左距离
840
+ * @param {Number} scrollTop 上距离
841
+ */
842
+ scrollTo (scrollLeft: number | null, scrollTop?: number | null) {
660
843
  const $xeTree = this
661
844
  const reactData = $xeTree.reactData
662
845
 
663
- return reactData.selectRadioKey || null
846
+ const scrollBodyElem = $xeTree.$refs.refVirtualWrapper as HTMLDivElement
847
+ if (scrollBodyElem) {
848
+ if (XEUtils.isNumber(scrollLeft)) {
849
+ scrollBodyElem.scrollLeft = scrollLeft
850
+ }
851
+ if (XEUtils.isNumber(scrollTop)) {
852
+ scrollBodyElem.scrollTop = scrollTop
853
+ }
854
+ }
855
+ if (reactData.scrollYLoad) {
856
+ return new Promise<void>(resolve => {
857
+ setTimeout(() => {
858
+ $xeTree.$nextTick(() => {
859
+ resolve()
860
+ })
861
+ }, 50)
862
+ })
863
+ }
864
+ return $xeTree.$nextTick()
664
865
  },
665
- setRadioNodeId (nodeKey: any) {
866
+ /**
867
+ * 刷新滚动条
868
+ */
869
+ refreshScroll () {
666
870
  const $xeTree = this
667
- const reactData = $xeTree.reactData
871
+ const internalData = $xeTree.internalData
668
872
 
669
- reactData.selectRadioKey = nodeKey
670
- return $xeTree.$nextTick()
873
+ const { lastScrollLeft, lastScrollTop } = internalData
874
+ return $xeTree.clearScroll().then(() => {
875
+ if (lastScrollLeft || lastScrollTop) {
876
+ internalData.lastScrollLeft = 0
877
+ internalData.lastScrollTop = 0
878
+ return scrollTo(lastScrollLeft, lastScrollTop)
879
+ }
880
+ })
671
881
  },
672
- getRadioNode () {
882
+ /**
883
+ * 重新计算列表
884
+ */
885
+ recalculate () {
673
886
  const $xeTree = this
674
887
  const reactData = $xeTree.reactData
675
888
  const internalData = $xeTree.internalData
676
889
 
677
- const { selectRadioKey } = reactData
678
- const { nodeMaps } = internalData
679
- if (selectRadioKey) {
680
- const nodeItem = nodeMaps[selectRadioKey]
681
- if (nodeItem) {
682
- return nodeItem.item
890
+ const { scrollYStore } = internalData
891
+ const { rowHeight } = scrollYStore
892
+ const el = $xeTree.$refs.refElem as HTMLDivElement
893
+ if (el && el.clientWidth && el.clientHeight) {
894
+ const parentEl = $xeTree.getParentElem()
895
+ const headerWrapperEl = $xeTree.$refs.refHeaderWrapperElem as HTMLDivElement
896
+ const footerWrapperEl = $xeTree.$refs.refFooterWrapperElem as HTMLDivElement
897
+ const headHeight = headerWrapperEl ? headerWrapperEl.clientHeight : 0
898
+ const footHeight = footerWrapperEl ? footerWrapperEl.clientHeight : 0
899
+ if (parentEl) {
900
+ const parentPaddingSize = getPaddingTopBottomSize(parentEl)
901
+ reactData.parentHeight = Math.max(headHeight + footHeight + rowHeight, parentEl.clientHeight - parentPaddingSize - headHeight - footHeight)
683
902
  }
903
+ $xeTree.updateHeight()
904
+ return $xeTree.computeScrollLoad()
684
905
  }
685
- return null
906
+ return $xeTree.$nextTick()
686
907
  },
687
- setRadioNode (node: any) {
908
+ loadYData (evnt: Event) {
688
909
  const $xeTree = this
689
- const reactData = $xeTree.reactData
910
+ const internalData = $xeTree.internalData
690
911
 
691
- if (node) {
692
- reactData.selectRadioKey = $xeTree.getNodeId(node)
912
+ const { scrollYStore } = internalData
913
+ const { startIndex, endIndex, visibleSize, offsetSize, rowHeight } = scrollYStore
914
+ const scrollBodyElem = evnt.target as HTMLDivElement
915
+ const scrollTop = scrollBodyElem.scrollTop
916
+ const toVisibleIndex = Math.floor(scrollTop / rowHeight)
917
+ const offsetStartIndex = Math.max(0, toVisibleIndex - 1 - offsetSize)
918
+ const offsetEndIndex = toVisibleIndex + visibleSize + offsetSize
919
+ if (toVisibleIndex <= startIndex || toVisibleIndex >= endIndex - visibleSize - 1) {
920
+ if (startIndex !== offsetStartIndex || endIndex !== offsetEndIndex) {
921
+ scrollYStore.startIndex = offsetStartIndex
922
+ scrollYStore.endIndex = offsetEndIndex
923
+ $xeTree.updateYData()
924
+ }
693
925
  }
694
- return $xeTree.$nextTick()
695
926
  },
696
- setCheckboxNode (nodeList: any | any[], checked: boolean) {
927
+ scrollEvent (evnt: Event) {
697
928
  const $xeTree = this
929
+ const reactData = $xeTree.reactData
930
+ const internalData = $xeTree.internalData
698
931
 
699
- if (nodeList) {
700
- if (!XEUtils.isArray(nodeList)) {
701
- nodeList = [nodeList]
702
- }
703
- $xeTree.handleCheckedCheckboxNode(nodeList, checked)
932
+ const scrollBodyElem = evnt.target as HTMLDivElement
933
+ const scrollTop = scrollBodyElem.scrollTop
934
+ const scrollLeft = scrollBodyElem.scrollLeft
935
+ const isX = scrollLeft !== internalData.lastScrollLeft
936
+ const isY = scrollTop !== internalData.lastScrollTop
937
+ internalData.lastScrollTop = scrollTop
938
+ internalData.lastScrollLeft = scrollLeft
939
+ if (reactData.scrollYLoad) {
940
+ $xeTree.loadYData(evnt)
704
941
  }
705
- return $xeTree.$nextTick()
942
+ internalData.lastScrollTime = Date.now()
943
+ $xeTree.dispatchEvent('scroll', { scrollLeft, scrollTop, isX, isY }, evnt)
706
944
  },
707
- setCheckboxByNodeId (nodeIds: any | any[], checked: boolean) {
945
+ clearScroll () {
708
946
  const $xeTree = this
709
947
  const internalData = $xeTree.internalData
710
948
 
711
- const { nodeMaps } = internalData
712
- if (nodeIds) {
713
- if (!XEUtils.isArray(nodeIds)) {
714
- nodeIds = [nodeIds]
715
- }
716
- const nodeList: any[] = []
717
- nodeIds.forEach((nodeid: string) => {
718
- const nodeItem = nodeMaps[nodeid]
719
- if (nodeItem) {
720
- nodeList.push(nodeItem.item)
721
- }
722
- })
723
- $xeTree.handleCheckedCheckboxNode(nodeList, checked)
949
+ const scrollBodyElem = $xeTree.$refs.refVirtualWrapper as HTMLDivElement
950
+ if (scrollBodyElem) {
951
+ scrollBodyElem.scrollTop = 0
952
+ scrollBodyElem.scrollLeft = 0
724
953
  }
954
+ internalData.lastScrollTop = 0
955
+ internalData.lastScrollLeft = 0
725
956
  return $xeTree.$nextTick()
726
957
  },
727
- handleCheckedCheckboxNode (nodeList: any[], checked: boolean) {
958
+ handleNodeClickEvent (evnt: MouseEvent, node: any) {
728
959
  const $xeTree = this
729
960
  const props = $xeTree
730
961
  const reactData = $xeTree.reactData
731
- const internalData = $xeTree.internalData
732
962
 
733
- const { transform } = props
734
- const { selectCheckboxMaps } = internalData
735
- const mapChildrenField = $xeTree.computeMapChildrenField
736
- const childrenField = $xeTree.computeChildrenField
737
- const checkboxOpts = $xeTree.computeCheckboxOpts
738
- const { checkStrictly } = checkboxOpts
739
- const handleSelect = (node: any) => {
740
- const nodeid = $xeTree.getNodeId(node)
741
- if (checked) {
742
- if (!selectCheckboxMaps[nodeid]) {
743
- selectCheckboxMaps[nodeid] = node
744
- }
745
- } else {
746
- if (selectCheckboxMaps[nodeid]) {
747
- delete selectCheckboxMaps[nodeid]
748
- }
749
- }
750
- }
751
- if (checkStrictly) {
752
- nodeList.forEach(handleSelect)
753
- } else {
754
- XEUtils.eachTree(nodeList, handleSelect, { children: transform ? mapChildrenField : childrenField })
755
- }
756
- reactData.updateCheckboxFlag++
757
- $xeTree.updateCheckboxStatus()
758
- },
759
- updateCheckboxChecked (nodeIds: VxeTreePropTypes.CheckNodeKeys) {
760
- const $xeTree = this
761
-
762
- $xeTree.setCheckboxByNodeId(nodeIds, true)
763
- },
764
- createNode (records: any[]) {
765
- const $xeTree = this
766
-
767
- const valueField = $xeTree.computeValueField
768
- return Promise.resolve(
769
- records.map(obj => {
770
- const item = { ...obj }
771
- let nodeid = $xeTree.getNodeId(item)
772
- if (!nodeid) {
773
- nodeid = getNodeUniqueId()
774
- XEUtils.set(item, valueField, nodeid)
775
- }
776
- return item
777
- })
778
- )
779
- },
780
- cacheNodeMap () {
781
- const $xeTree = this
782
- const props = $xeTree
783
- const reactData = $xeTree.reactData
784
- const internalData = $xeTree.internalData
785
-
786
- const { transform } = props
787
- const { treeList } = reactData
788
- const valueField = $xeTree.computeValueField
789
- const childrenField = $xeTree.computeChildrenField
790
- const mapChildrenField = $xeTree.computeMapChildrenField
791
- const keyMaps: Record<string, VxeTreeDefines.NodeCacheItem> = {}
792
- XEUtils.eachTree(treeList, (item, itemIndex, items, path, parent, nodes) => {
793
- let nodeid = $xeTree.getNodeId(item)
794
- if (!nodeid) {
795
- nodeid = getNodeUniqueId()
796
- XEUtils.set(item, valueField, nodeid)
797
- }
798
- keyMaps[nodeid] = {
799
- item,
800
- itemIndex,
801
- items,
802
- parent,
803
- nodes,
804
- level: nodes.length,
805
- lineCount: 0,
806
- treeLoaded: false
807
- }
808
- }, { children: transform ? mapChildrenField : childrenField })
809
- internalData.nodeMaps = keyMaps
810
- },
811
- loadTreeData (list: any[]) {
812
- const $xeTree = this
813
- const props = $xeTree
814
- const reactData = $xeTree.reactData
815
- const internalData = $xeTree.internalData
816
-
817
- const { expandAll, transform } = props
818
- const { initialized } = internalData
819
- const keyField = $xeTree.computeKeyField
820
- const parentField = $xeTree.computeParentField
821
- const mapChildrenField = $xeTree.computeMapChildrenField
822
- if (transform) {
823
- reactData.treeList = XEUtils.toArrayTree(list, { key: keyField, parentKey: parentField, mapChildren: mapChildrenField })
824
- } else {
825
- reactData.treeList = list ? list.slice(0) : []
826
- }
827
- $xeTree.cacheNodeMap()
828
- if (!initialized) {
829
- if (list && list.length) {
830
- internalData.initialized = true
831
- if (expandAll) {
832
- $xeTree.setAllExpandNode(true)
833
- }
834
- $xeTree.setCheckboxByNodeId(props.checkNodeKeys || [], true)
835
- }
836
- }
837
- },
838
- handleCountLine (item: any, isRoot: boolean, nodeItem: VxeTreeDefines.NodeCacheItem) {
839
- const $xeTree = this
840
- const internalData = $xeTree.internalData
841
-
842
- const { treeExpandedMaps } = internalData
843
- const childrenField = $xeTree.computeChildrenField
844
- const nodeid = $xeTree.getNodeId(item)
845
- nodeItem.lineCount++
846
- if (treeExpandedMaps[nodeid]) {
847
- XEUtils.arrayEach(item[childrenField], (childItem, childIndex, childList) => {
848
- if (!isRoot || childIndex < childList.length - 1) {
849
- $xeTree.handleCountLine(childItem, false, nodeItem)
850
- }
851
- })
852
- }
853
- },
854
- updateNodeLine (node: any) {
855
- const $xeTree = this
856
- const internalData = $xeTree.internalData
857
-
858
- const { nodeMaps } = internalData
859
- if (node) {
860
- const nodeid = $xeTree.getNodeId(node)
861
- const nodeItem = nodeMaps[nodeid]
862
- if (nodeItem) {
863
- XEUtils.lastArrayEach(nodeItem.nodes, childItem => {
864
- const nodeid = $xeTree.getNodeId(childItem)
865
- const nodeItem = nodeMaps[nodeid]
866
- if (nodeItem) {
867
- nodeItem.lineCount = 0
868
- $xeTree.handleCountLine(childItem, true, nodeItem)
869
- }
870
- })
871
- }
872
- }
873
- },
874
- handleNodeClickEvent (evnt: MouseEvent, node: any) {
875
- const $xeTree = this
876
- const props = $xeTree
877
- const reactData = $xeTree.reactData
878
-
879
- const { showRadio, showCheckbox, trigger } = props
880
- const radioOpts = $xeTree.computeRadioOpts
963
+ const { showRadio, showCheckbox, trigger } = props
964
+ const radioOpts = $xeTree.computeRadioOpts
881
965
  const checkboxOpts = $xeTree.computeCheckboxOpts
882
966
  const isRowCurrent = $xeTree.computeIsRowCurrent
883
967
  let triggerCurrent = false
@@ -904,12 +988,12 @@ export default /* define-vxe-component start */ defineVxeComponent({
904
988
  }
905
989
  $xeTree.dispatchEvent('node-click', { node, triggerCurrent, triggerRadio, triggerCheckbox, triggerExpand }, evnt)
906
990
  },
907
- handleNodeDblclickEvent (evnt: MouseEvent, node: any) {
991
+ handleNodeDblclickEvent (evnt: MouseEvent, node: any) {
908
992
  const $xeTree = this
909
993
 
910
994
  $xeTree.dispatchEvent('node-dblclick', { node }, evnt)
911
995
  },
912
- handleAsyncTreeExpandChilds (node: any): Promise<void> {
996
+ handleAsyncTreeExpandChilds (node: any) {
913
997
  const $xeTree = this
914
998
  const props = $xeTree
915
999
  const reactData = $xeTree.reactData
@@ -918,7 +1002,7 @@ export default /* define-vxe-component start */ defineVxeComponent({
918
1002
  const checkboxOpts = $xeTree.computeCheckboxOpts
919
1003
  const { loadMethod } = props
920
1004
  const { checkStrictly } = checkboxOpts
921
- return new Promise(resolve => {
1005
+ return new Promise<void>(resolve => {
922
1006
  if (loadMethod) {
923
1007
  const { nodeMaps } = internalData
924
1008
  const nodeid = $xeTree.getNodeId(node)
@@ -946,12 +1030,10 @@ export default /* define-vxe-component start */ defineVxeComponent({
946
1030
  if (!checkStrictly && $xeTree.isCheckedByCheckboxNodeId(nodeid)) {
947
1031
  $xeTree.handleCheckedCheckboxNode(childRows, true)
948
1032
  }
949
- $xeTree.updateNodeLine(node)
950
1033
  $xeTree.dispatchEvent('load-success', { node, data: childRecords }, new Event('load-success'))
951
1034
  return $xeTree.$nextTick()
952
1035
  })
953
1036
  } else {
954
- $xeTree.updateNodeLine(node)
955
1037
  $xeTree.dispatchEvent('load-success', { node, data: childRecords }, new Event('load-success'))
956
1038
  }
957
1039
  }).catch((e) => {
@@ -960,10 +1042,11 @@ export default /* define-vxe-component start */ defineVxeComponent({
960
1042
  if (treeExpandLazyLoadedMaps[nodeid]) {
961
1043
  treeExpandLazyLoadedMaps[nodeid] = false
962
1044
  }
963
- $xeTree.updateNodeLine(node)
964
1045
  $xeTree.dispatchEvent('load-error', { node, data: e }, new Event('load-error'))
965
1046
  }).finally(() => {
966
- return $xeTree.$nextTick()
1047
+ $xeTree.handleTreeToList()
1048
+ $xeTree.handleData()
1049
+ return $xeTree.recalculate()
967
1050
  })
968
1051
  } else {
969
1052
  resolve()
@@ -1031,8 +1114,9 @@ export default /* define-vxe-component start */ defineVxeComponent({
1031
1114
  })
1032
1115
  }
1033
1116
  reactData.updateExpandedFlag++
1034
- expandNodes.forEach($xeTree.updateNodeLine)
1035
- return Promise.all(result)
1117
+ $xeTree.handleTreeToList()
1118
+ $xeTree.handleData()
1119
+ return Promise.all(result).then(() => $xeTree.recalculate())
1036
1120
  },
1037
1121
  toggleExpandEvent (evnt: MouseEvent, node: any) {
1038
1122
  const $xeTree = this
@@ -1048,15 +1132,14 @@ export default /* define-vxe-component start */ defineVxeComponent({
1048
1132
  $xeTree.handleBaseTreeExpand([node], expanded)
1049
1133
  }
1050
1134
  },
1051
- updateCheckboxStatus () {
1135
+ updateCheckboxStatus () {
1052
1136
  const $xeTree = this
1053
1137
  const props = $xeTree
1054
1138
  const reactData = $xeTree.reactData
1055
1139
  const internalData = $xeTree.internalData
1056
1140
 
1057
1141
  const { transform } = props
1058
- const { treeList } = reactData
1059
- const { selectCheckboxMaps, indeterminateRowMaps } = internalData
1142
+ const { selectCheckboxMaps, indeterminateRowMaps, afterTreeList } = internalData
1060
1143
  const childrenField = $xeTree.computeChildrenField
1061
1144
  const mapChildrenField = $xeTree.computeMapChildrenField
1062
1145
  const checkboxOpts = $xeTree.computeCheckboxOpts
@@ -1064,7 +1147,7 @@ export default /* define-vxe-component start */ defineVxeComponent({
1064
1147
  if (!checkStrictly) {
1065
1148
  const childRowMaps: Record<string, number> = {}
1066
1149
  const childRowList: any[][] = []
1067
- XEUtils.eachTree(treeList, (node) => {
1150
+ XEUtils.eachTree(afterTreeList, (node) => {
1068
1151
  const nodeid = $xeTree.getNodeId(node)
1069
1152
  const childList = node[childrenField]
1070
1153
  if (childList && childList.length && !childRowMaps[nodeid]) {
@@ -1079,13 +1162,14 @@ export default /* define-vxe-component start */ defineVxeComponent({
1079
1162
  const childList: any[] = vals[2]
1080
1163
  let sLen = 0 // 已选
1081
1164
  let hLen = 0 // 半选
1082
- let vLen = 0 // 有效行
1165
+ let vLen = 0 // 有效子行
1166
+ const cLen = childList.length // 子行
1083
1167
  childList.forEach(
1084
1168
  checkMethod
1085
1169
  ? (item) => {
1086
1170
  const childNodeid = $xeTree.getNodeId(item)
1087
1171
  const isSelect = selectCheckboxMaps[childNodeid]
1088
- if (checkMethod({ node: item })) {
1172
+ if (checkMethod({ $tree: $xeTree, node: item })) {
1089
1173
  if (isSelect) {
1090
1174
  sLen++
1091
1175
  } else if (indeterminateRowMaps[childNodeid]) {
@@ -1111,8 +1195,27 @@ export default /* define-vxe-component start */ defineVxeComponent({
1111
1195
  vLen++
1112
1196
  }
1113
1197
  )
1114
- const isSelected = sLen >= vLen
1115
- const halfSelect = !isSelected && (sLen >= 1 || hLen >= 1)
1198
+
1199
+ let isSelected = false
1200
+ if (cLen > 0) {
1201
+ if (vLen > 0) {
1202
+ isSelected = (sLen > 0 || hLen > 0) && sLen >= vLen
1203
+ } else {
1204
+ // 如果存在子项禁用
1205
+ if ((sLen > 0 && sLen >= vLen)) {
1206
+ isSelected = true
1207
+ } else if (selectCheckboxMaps[nodeid]) {
1208
+ isSelected = true
1209
+ } else {
1210
+ isSelected = false
1211
+ }
1212
+ }
1213
+ } else {
1214
+ // 如果无子项
1215
+ isSelected = selectCheckboxMaps[nodeid]
1216
+ }
1217
+ const halfSelect = !isSelected && (sLen > 0 || hLen > 0)
1218
+
1116
1219
  if (isSelected) {
1117
1220
  selectCheckboxMaps[nodeid] = node
1118
1221
  if (indeterminateRowMaps[nodeid]) {
@@ -1131,108 +1234,489 @@ export default /* define-vxe-component start */ defineVxeComponent({
1131
1234
  }
1132
1235
  }
1133
1236
  })
1134
- reactData.updateCheckboxFlag++
1237
+ reactData.updateCheckboxFlag++
1238
+ }
1239
+ },
1240
+ changeCheckboxEvent (evnt: MouseEvent, node: any) {
1241
+ const $xeTree = this
1242
+ const props = $xeTree
1243
+ const reactData = $xeTree.reactData
1244
+ const internalData = $xeTree.internalData
1245
+
1246
+ evnt.preventDefault()
1247
+ evnt.stopPropagation()
1248
+ const { transform } = props
1249
+ const { selectCheckboxMaps } = internalData
1250
+ const childrenField = $xeTree.computeChildrenField
1251
+ const mapChildrenField = $xeTree.computeMapChildrenField
1252
+ const checkboxOpts = $xeTree.computeCheckboxOpts
1253
+ const { checkStrictly, checkMethod } = checkboxOpts
1254
+ let isDisabled = !!checkMethod
1255
+ if (checkMethod) {
1256
+ isDisabled = !checkMethod({ $tree: $xeTree, node })
1257
+ }
1258
+ if (isDisabled) {
1259
+ return
1260
+ }
1261
+ const nodeid = $xeTree.getNodeId(node)
1262
+ let isChecked = false
1263
+ if (selectCheckboxMaps[nodeid]) {
1264
+ delete selectCheckboxMaps[nodeid]
1265
+ } else {
1266
+ isChecked = true
1267
+ selectCheckboxMaps[nodeid] = node
1268
+ }
1269
+ if (!checkStrictly) {
1270
+ XEUtils.eachTree(XEUtils.get(node, transform ? mapChildrenField : childrenField), (childNode) => {
1271
+ const childNodeid = $xeTree.getNodeId(childNode)
1272
+ if (isChecked) {
1273
+ if (!selectCheckboxMaps[childNodeid]) {
1274
+ selectCheckboxMaps[childNodeid] = true
1275
+ }
1276
+ } else {
1277
+ if (selectCheckboxMaps[childNodeid]) {
1278
+ delete selectCheckboxMaps[childNodeid]
1279
+ }
1280
+ }
1281
+ }, { children: transform ? mapChildrenField : childrenField })
1282
+ }
1283
+ reactData.updateCheckboxFlag++
1284
+ $xeTree.updateCheckboxStatus()
1285
+ const value = XEUtils.keys(selectCheckboxMaps)
1286
+ $xeTree.emitCheckboxMode(value)
1287
+ $xeTree.dispatchEvent('checkbox-change', { node, value, checked: isChecked }, evnt)
1288
+ },
1289
+ changeCurrentEvent (evnt: MouseEvent, node: any) {
1290
+ const $xeTree = this
1291
+ const reactData = $xeTree.reactData
1292
+
1293
+ evnt.preventDefault()
1294
+ const nodeOpts = $xeTree.computeNodeOpts
1295
+ const { currentMethod, trigger } = nodeOpts
1296
+ const childrenField = $xeTree.computeChildrenField
1297
+ const childList: any[] = XEUtils.get(node, childrenField)
1298
+ const hasChild = childList && childList.length
1299
+ let isDisabled = !!currentMethod
1300
+ if (trigger === 'child') {
1301
+ if (hasChild) {
1302
+ return
1303
+ }
1304
+ } else if (trigger === 'parent') {
1305
+ if (!hasChild) {
1306
+ return
1307
+ }
1308
+ }
1309
+ if (currentMethod) {
1310
+ isDisabled = !currentMethod({ node })
1311
+ }
1312
+ if (isDisabled) {
1313
+ return
1314
+ }
1315
+ const isChecked = true
1316
+ reactData.currentNode = node
1317
+ $xeTree.dispatchEvent('current-change', { node, checked: isChecked }, evnt)
1318
+ },
1319
+ changeRadioEvent (evnt: MouseEvent, node: any) {
1320
+ const $xeTree = this
1321
+ const reactData = $xeTree.reactData
1322
+
1323
+ evnt.preventDefault()
1324
+ evnt.stopPropagation()
1325
+ const radioOpts = $xeTree.computeRadioOpts
1326
+ const { checkMethod } = radioOpts
1327
+ let isDisabled = !!checkMethod
1328
+ if (checkMethod) {
1329
+ isDisabled = !checkMethod({ $tree: $xeTree, node })
1330
+ }
1331
+ if (isDisabled) {
1332
+ return
1333
+ }
1334
+ const isChecked = true
1335
+ const value = $xeTree.getNodeId(node)
1336
+ reactData.selectRadioKey = value
1337
+ $xeTree.emitRadioMode(value)
1338
+ $xeTree.dispatchEvent('radio-change', { node, value, checked: isChecked }, evnt)
1339
+ },
1340
+ handleGlobalResizeEvent () {
1341
+ const $xeTree = this
1342
+
1343
+ const el = $xeTree.$refs.refElem as HTMLDivElement
1344
+ if (!el || !el.clientWidth) {
1345
+ return
1346
+ }
1347
+ $xeTree.recalculate()
1348
+ },
1349
+ reloadData (data: any[]) {
1350
+ const $xeTree = this
1351
+
1352
+ return $xeTree.loadData(data || [])
1353
+ },
1354
+ clearCurrentNode () {
1355
+ const $xeTree = this
1356
+ const reactData = $xeTree.reactData
1357
+
1358
+ reactData.currentNode = null
1359
+ return $xeTree.$nextTick()
1360
+ },
1361
+ getCurrentNodeId () {
1362
+ const $xeTree = this
1363
+ const reactData = $xeTree.reactData
1364
+
1365
+ const { currentNode } = reactData
1366
+ if (currentNode) {
1367
+ return $xeTree.getNodeId(currentNode)
1368
+ }
1369
+ return null
1370
+ },
1371
+ getCurrentNode () {
1372
+ const $xeTree = this
1373
+ const reactData = $xeTree.reactData
1374
+ const internalData = $xeTree.internalData
1375
+
1376
+ const { currentNode } = reactData
1377
+ const { nodeMaps } = internalData
1378
+ if (currentNode) {
1379
+ const nodeItem = nodeMaps[$xeTree.getNodeId(currentNode)]
1380
+ if (nodeItem) {
1381
+ return nodeItem.item
1382
+ }
1383
+ }
1384
+ return null
1385
+ },
1386
+ setCurrentNodeId (nodeKey: any) {
1387
+ const $xeTree = this
1388
+ const reactData = $xeTree.reactData
1389
+ const internalData = $xeTree.internalData
1390
+
1391
+ const { nodeMaps } = internalData
1392
+ const nodeItem = nodeMaps[nodeKey]
1393
+ reactData.currentNode = nodeItem ? nodeItem.item : null
1394
+ return $xeTree.$nextTick()
1395
+ },
1396
+ setCurrentNode (node: any) {
1397
+ const $xeTree = this
1398
+ const reactData = $xeTree.reactData
1399
+
1400
+ reactData.currentNode = node
1401
+ return $xeTree.$nextTick()
1402
+ },
1403
+ clearRadioNode () {
1404
+ const $xeTree = this
1405
+ const reactData = $xeTree.reactData
1406
+
1407
+ reactData.selectRadioKey = null
1408
+ return $xeTree.$nextTick()
1409
+ },
1410
+ getRadioNodeId () {
1411
+ const $xeTree = this
1412
+ const reactData = $xeTree.reactData
1413
+
1414
+ return reactData.selectRadioKey || null
1415
+ },
1416
+ getRadioNode () {
1417
+ const $xeTree = this
1418
+ const reactData = $xeTree.reactData
1419
+ const internalData = $xeTree.internalData
1420
+
1421
+ const { selectRadioKey } = reactData
1422
+ const { nodeMaps } = internalData
1423
+ if (selectRadioKey) {
1424
+ const nodeItem = nodeMaps[selectRadioKey]
1425
+ if (nodeItem) {
1426
+ return nodeItem.item
1427
+ }
1428
+ }
1429
+ return null
1430
+ },
1431
+ setRadioNodeId (nodeKey: any) {
1432
+ const $xeTree = this
1433
+ const reactData = $xeTree.reactData
1434
+
1435
+ reactData.selectRadioKey = nodeKey
1436
+ return $xeTree.$nextTick()
1437
+ },
1438
+ getCheckboxNodeIds () {
1439
+ const $xeTree = this
1440
+ const internalData = $xeTree.internalData
1441
+
1442
+ const { selectCheckboxMaps } = internalData
1443
+ return Object.keys(selectCheckboxMaps)
1444
+ },
1445
+ getCheckboxNodes () {
1446
+ const $xeTree = this
1447
+ const internalData = $xeTree.internalData
1448
+
1449
+ const { nodeMaps, selectCheckboxMaps } = internalData
1450
+ const list: any[] = []
1451
+ XEUtils.each(selectCheckboxMaps, (item, nodeid) => {
1452
+ const nodeItem = nodeMaps[nodeid]
1453
+ if (nodeItem) {
1454
+ list.push(nodeItem.item)
1455
+ }
1456
+ })
1457
+ return list
1458
+ },
1459
+ clearCheckboxNode () {
1460
+ const $xeTree = this
1461
+ const reactData = $xeTree.reactData
1462
+ const internalData = $xeTree.internalData
1463
+
1464
+ internalData.selectCheckboxMaps = {}
1465
+ reactData.updateCheckboxFlag++
1466
+ return $xeTree.$nextTick().then(() => {
1467
+ return { checkNodeKeys: [] }
1468
+ })
1469
+ },
1470
+ setAllCheckboxNode (checked: boolean) {
1471
+ const $xeTree = this
1472
+ const props = $xeTree
1473
+ const reactData = $xeTree.reactData
1474
+ const internalData = $xeTree.internalData
1475
+
1476
+ const { transform } = props
1477
+ const selectMaps: Record<string, boolean> = {}
1478
+ const childrenField = $xeTree.computeChildrenField
1479
+ const mapChildrenField = $xeTree.computeMapChildrenField
1480
+ const checkKeys: string[] = []
1481
+ if (checked) {
1482
+ XEUtils.eachTree(internalData.afterTreeList, (node) => {
1483
+ const nodeid = $xeTree.getNodeId(node)
1484
+ checkKeys.push(nodeid)
1485
+ selectMaps[nodeid] = true
1486
+ }, { children: transform ? mapChildrenField : childrenField })
1487
+ }
1488
+ internalData.selectCheckboxMaps = selectMaps
1489
+ reactData.updateCheckboxFlag++
1490
+ return $xeTree.$nextTick().then(() => {
1491
+ return { checkNodeKeys: checkKeys }
1492
+ })
1493
+ },
1494
+ clearExpandNode () {
1495
+ const $xeTree = this
1496
+
1497
+ return $xeTree.clearAllExpandNode()
1498
+ },
1499
+ clearAllExpandNode () {
1500
+ const $xeTree = this
1501
+ const reactData = $xeTree.reactData
1502
+ const internalData = $xeTree.internalData
1503
+
1504
+ const { nodeMaps } = internalData
1505
+ XEUtils.each(nodeMaps, (nodeItem: VxeTreeDefines.NodeCacheItem) => {
1506
+ nodeItem.treeLoaded = false
1507
+ })
1508
+ internalData.treeExpandedMaps = {}
1509
+ reactData.updateExpandedFlag++
1510
+ $xeTree.handleTreeToList()
1511
+ $xeTree.handleData()
1512
+ return $xeTree.recalculate()
1513
+ },
1514
+ setExpandByNodeId (nodeids: any, expanded: boolean) {
1515
+ const $xeTree = this
1516
+ const reactData = $xeTree.reactData
1517
+ const internalData = $xeTree.internalData
1518
+
1519
+ const { treeExpandedMaps } = internalData
1520
+ if (nodeids) {
1521
+ if (!XEUtils.isArray(nodeids)) {
1522
+ nodeids = [nodeids]
1523
+ }
1524
+ nodeids.forEach((nodeid: string) => {
1525
+ handleSetExpand(nodeid, expanded, treeExpandedMaps)
1526
+ })
1527
+ reactData.updateExpandedFlag++
1528
+ }
1529
+ $xeTree.handleTreeToList()
1530
+ $xeTree.handleData()
1531
+ return $xeTree.recalculate()
1532
+ },
1533
+ getExpandNodeIds () {
1534
+ const $xeTree = this
1535
+ const internalData = $xeTree.internalData
1536
+
1537
+ const { treeExpandedMaps } = internalData
1538
+ return XEUtils.keys(treeExpandedMaps)
1539
+ },
1540
+ getExpandNodes () {
1541
+ const $xeTree = this
1542
+ const internalData = $xeTree.internalData
1543
+
1544
+ const { nodeMaps, treeExpandedMaps } = internalData
1545
+ const list: any[] = []
1546
+ XEUtils.each(treeExpandedMaps, (item, nodeid) => {
1547
+ const nodeItem = nodeMaps[nodeid]
1548
+ if (nodeItem) {
1549
+ list.push(nodeItem.item)
1550
+ }
1551
+ })
1552
+ return list
1553
+ },
1554
+ setExpandNode (nodes: any, expanded: boolean) {
1555
+ const $xeTree = this
1556
+ const reactData = $xeTree.reactData
1557
+ const internalData = $xeTree.internalData
1558
+
1559
+ const { treeExpandedMaps } = internalData
1560
+ if (nodes) {
1561
+ if (!XEUtils.isArray(nodes)) {
1562
+ nodes = [nodes]
1563
+ }
1564
+ nodes.forEach((node: any) => {
1565
+ const nodeid = $xeTree.getNodeId(node)
1566
+ handleSetExpand(nodeid, expanded, treeExpandedMaps)
1567
+ })
1568
+ reactData.updateExpandedFlag++
1569
+ }
1570
+ $xeTree.handleTreeToList()
1571
+ $xeTree.handleData()
1572
+ return $xeTree.recalculate()
1573
+ },
1574
+ toggleExpandByNodeId (nodeids: any) {
1575
+ const $xeTree = this
1576
+ const reactData = $xeTree.reactData
1577
+ const internalData = $xeTree.internalData
1578
+
1579
+ const { treeExpandedMaps } = internalData
1580
+ if (nodeids) {
1581
+ if (!XEUtils.isArray(nodeids)) {
1582
+ nodeids = [nodeids]
1583
+ }
1584
+ nodeids.forEach((nodeid: string) => {
1585
+ handleSetExpand(nodeid, !treeExpandedMaps[nodeid], treeExpandedMaps)
1586
+ })
1587
+ reactData.updateExpandedFlag++
1588
+ }
1589
+ $xeTree.handleTreeToList()
1590
+ $xeTree.handleData()
1591
+ return $xeTree.recalculate()
1592
+ },
1593
+ toggleExpandNode (nodes: any) {
1594
+ const $xeTree = this
1595
+ const reactData = $xeTree.reactData
1596
+ const internalData = $xeTree.internalData
1597
+
1598
+ const { treeExpandedMaps } = internalData
1599
+ if (nodes) {
1600
+ if (!XEUtils.isArray(nodes)) {
1601
+ nodes = [nodes]
1602
+ }
1603
+ nodes.forEach((node: any) => {
1604
+ const nodeid = $xeTree.getNodeId(node)
1605
+ handleSetExpand(nodeid, !treeExpandedMaps[nodeid], treeExpandedMaps)
1606
+ })
1607
+ reactData.updateExpandedFlag++
1135
1608
  }
1609
+ $xeTree.handleTreeToList()
1610
+ $xeTree.handleData()
1611
+ return $xeTree.recalculate()
1136
1612
  },
1137
- changeCheckboxEvent (evnt: MouseEvent, node: any) {
1613
+ setAllExpandNode (expanded: boolean) {
1138
1614
  const $xeTree = this
1139
1615
  const props = $xeTree
1140
1616
  const reactData = $xeTree.reactData
1141
1617
  const internalData = $xeTree.internalData
1142
1618
 
1143
- evnt.preventDefault()
1144
- evnt.stopPropagation()
1145
1619
  const { transform } = props
1146
- const { selectCheckboxMaps } = internalData
1620
+ const { treeExpandedMaps } = internalData
1147
1621
  const childrenField = $xeTree.computeChildrenField
1148
1622
  const mapChildrenField = $xeTree.computeMapChildrenField
1149
- const checkboxOpts = $xeTree.computeCheckboxOpts
1150
- const { checkStrictly, checkMethod } = checkboxOpts
1151
- let isDisabled = !!checkMethod
1152
- if (checkMethod) {
1153
- isDisabled = !checkMethod({ node })
1154
- }
1155
- if (isDisabled) {
1156
- return
1157
- }
1158
- const nodeid = $xeTree.getNodeId(node)
1159
- let isChecked = false
1160
- if (selectCheckboxMaps[nodeid]) {
1161
- delete selectCheckboxMaps[nodeid]
1162
- } else {
1163
- isChecked = true
1164
- selectCheckboxMaps[nodeid] = node
1165
- }
1166
- if (!checkStrictly) {
1167
- XEUtils.eachTree(XEUtils.get(node, childrenField), (childNode) => {
1168
- const childNodeid = $xeTree.getNodeId(childNode)
1169
- if (isChecked) {
1170
- if (!selectCheckboxMaps[childNodeid]) {
1171
- selectCheckboxMaps[childNodeid] = true
1172
- }
1173
- } else {
1174
- if (selectCheckboxMaps[childNodeid]) {
1175
- delete selectCheckboxMaps[childNodeid]
1176
- }
1623
+ if (expanded) {
1624
+ XEUtils.eachTree(internalData.afterTreeList, (node) => {
1625
+ const childList: any[] = XEUtils.get(node, childrenField)
1626
+ const hasChild = childList && childList.length
1627
+ if (hasChild) {
1628
+ const nodeid = $xeTree.getNodeId(node)
1629
+ treeExpandedMaps[nodeid] = true
1177
1630
  }
1178
1631
  }, { children: transform ? mapChildrenField : childrenField })
1632
+ } else {
1633
+ internalData.treeExpandedMaps = {}
1179
1634
  }
1180
- reactData.updateCheckboxFlag++
1181
- $xeTree.updateCheckboxStatus()
1182
- const value = XEUtils.keys(selectCheckboxMaps)
1183
- $xeTree.emitCheckboxMode(value)
1184
- $xeTree.dispatchEvent('checkbox-change', { node, value, checked: isChecked }, evnt)
1635
+ reactData.updateExpandedFlag++
1636
+ $xeTree.handleTreeToList()
1637
+ $xeTree.handleData()
1638
+ return $xeTree.recalculate()
1185
1639
  },
1186
- changeCurrentEvent (evnt: MouseEvent, node: any) {
1640
+ reloadExpandNode (node: any) {
1187
1641
  const $xeTree = this
1188
- const reactData = $xeTree.reactData
1642
+ const props = $xeTree
1189
1643
 
1190
- evnt.preventDefault()
1191
- const nodeOpts = $xeTree.computeNodeOpts
1192
- const { currentMethod, trigger } = nodeOpts
1193
- const childrenField = $xeTree.computeChildrenField
1194
- const childList: any[] = XEUtils.get(node, childrenField)
1195
- const hasChild = childList && childList.length
1196
- let isDisabled = !!currentMethod
1197
- if (trigger === 'child') {
1198
- if (hasChild) {
1199
- return
1200
- }
1201
- } else if (trigger === 'parent') {
1202
- if (!hasChild) {
1203
- return
1204
- }
1205
- }
1206
- if (currentMethod) {
1207
- isDisabled = !currentMethod({ node })
1208
- }
1209
- if (isDisabled) {
1210
- return
1644
+ const { lazy } = props
1645
+ if (lazy) {
1646
+ $xeTree.clearExpandLoaded(node)
1647
+ return $xeTree.handleAsyncTreeExpandChilds(node)
1211
1648
  }
1212
- const isChecked = true
1213
- reactData.currentNode = node
1214
- $xeTree.dispatchEvent('current-change', { node, checked: isChecked }, evnt)
1649
+ return $xeTree.recalculate()
1215
1650
  },
1216
- changeRadioEvent (evnt: MouseEvent, node: any) {
1651
+ clearExpandLoaded (node: any) {
1217
1652
  const $xeTree = this
1218
- const reactData = $xeTree.reactData
1653
+ const props = $xeTree
1654
+ const internalData = $xeTree.internalData
1219
1655
 
1220
- evnt.preventDefault()
1221
- evnt.stopPropagation()
1222
- const radioOpts = $xeTree.computeRadioOpts
1223
- const { checkMethod } = radioOpts
1224
- let isDisabled = !!checkMethod
1225
- if (checkMethod) {
1226
- isDisabled = !checkMethod({ node })
1656
+ const { lazy } = props
1657
+ const { nodeMaps } = internalData
1658
+ if (lazy) {
1659
+ const nodeItem = nodeMaps[$xeTree.getNodeId(node)]
1660
+ if (nodeItem) {
1661
+ nodeItem.treeLoaded = false
1662
+ }
1227
1663
  }
1228
- if (isDisabled) {
1229
- return
1664
+ return $xeTree.recalculate()
1665
+ },
1666
+ /**
1667
+ * 用于树结构,给行数据加载子节点
1668
+ */
1669
+ loadChildrenNode (node: any, childRecords: any[]) {
1670
+ const $xeTree = this
1671
+ const props = $xeTree
1672
+ const internalData = $xeTree.internalData
1673
+
1674
+ const { lazy, transform } = props
1675
+ const { nodeMaps } = internalData
1676
+ if (!lazy) {
1677
+ return Promise.resolve([])
1230
1678
  }
1231
- const isChecked = true
1232
- const value = $xeTree.getNodeId(node)
1233
- reactData.selectRadioKey = value
1234
- $xeTree.emitRadioMode(value)
1235
- $xeTree.dispatchEvent('radio-change', { node, value, checked: isChecked }, evnt)
1679
+ const childrenField = $xeTree.computeChildrenField
1680
+ const mapChildrenField = $xeTree.computeMapChildrenField
1681
+ const parentNodeItem = nodeMaps[$xeTree.getNodeId(node)]
1682
+ const parentLevel = parentNodeItem ? parentNodeItem.level : 0
1683
+ const parentNodes = parentNodeItem ? parentNodeItem.nodes : []
1684
+ return $xeTree.createNode(childRecords).then((nodeList) => {
1685
+ XEUtils.eachTree(nodeList, (childRow, index, items, path, parent, nodes) => {
1686
+ const itemNodeId = $xeTree.getNodeId(childRow)
1687
+ nodeMaps[itemNodeId] = {
1688
+ item: node,
1689
+ index: -1,
1690
+ items,
1691
+ parent: parent || parentNodeItem.item,
1692
+ nodes: parentNodes.concat(nodes),
1693
+ level: parentLevel + nodes.length,
1694
+ treeIndex: -1,
1695
+ lineCount: 0,
1696
+ treeLoaded: false
1697
+ }
1698
+ }, { children: childrenField })
1699
+ node[childrenField] = nodeList
1700
+ if (transform) {
1701
+ node[mapChildrenField] = nodeList
1702
+ }
1703
+ $xeTree.updateAfterDataIndex()
1704
+ return nodeList
1705
+ })
1706
+ },
1707
+ getCheckboxIndeterminateNodes () {
1708
+ const $xeTree = this
1709
+ const internalData = $xeTree.internalData
1710
+
1711
+ const { nodeMaps, indeterminateRowMaps } = internalData
1712
+ const list: any[] = []
1713
+ XEUtils.each(indeterminateRowMaps, (item, nodeid) => {
1714
+ const nodeItem = nodeMaps[nodeid]
1715
+ if (nodeItem) {
1716
+ list.push(nodeItem.item)
1717
+ }
1718
+ })
1719
+ return list
1236
1720
  },
1237
1721
 
1238
1722
  //
@@ -1245,11 +1729,11 @@ export default /* define-vxe-component start */ defineVxeComponent({
1245
1729
  const { showRadio } = props
1246
1730
  const radioOpts = $xeTree.computeRadioOpts
1247
1731
  const { showIcon, checkMethod, visibleMethod } = radioOpts
1248
- const isVisible = !visibleMethod || visibleMethod({ node })
1732
+ const isVisible = !visibleMethod || visibleMethod({ $tree: $xeTree, node })
1249
1733
  let isDisabled = !!checkMethod
1250
1734
  if (showRadio && showIcon && isVisible) {
1251
1735
  if (checkMethod) {
1252
- isDisabled = !checkMethod({ node })
1736
+ isDisabled = !checkMethod({ $tree: $xeTree, node })
1253
1737
  }
1254
1738
  return h('div', {
1255
1739
  class: ['vxe-tree--radio-option', {
@@ -1279,11 +1763,11 @@ export default /* define-vxe-component start */ defineVxeComponent({
1279
1763
  const checkboxOpts = $xeTree.computeCheckboxOpts
1280
1764
  const { showIcon, checkMethod, visibleMethod } = checkboxOpts
1281
1765
  const isIndeterminate = $xeTree.isIndeterminateByCheckboxNodeid(nodeid)
1282
- const isVisible = !visibleMethod || visibleMethod({ node })
1766
+ const isVisible = !visibleMethod || visibleMethod({ $tree: $xeTree, node })
1283
1767
  let isDisabled = !!checkMethod
1284
1768
  if (showCheckbox && showIcon && isVisible) {
1285
1769
  if (checkMethod) {
1286
- isDisabled = !checkMethod({ node })
1770
+ isDisabled = !checkMethod({ $tree: $xeTree, node })
1287
1771
  }
1288
1772
  return h('div', {
1289
1773
  class: ['vxe-tree--checkbox-option', {
@@ -1306,7 +1790,7 @@ export default /* define-vxe-component start */ defineVxeComponent({
1306
1790
  }
1307
1791
  return renderEmptyElement($xeTree)
1308
1792
  },
1309
- renderNode (h: CreateElement, node: any): VNode {
1793
+ renderNode (h: CreateElement, node: any, nodeid: string) {
1310
1794
  const $xeTree = this
1311
1795
  const props = $xeTree
1312
1796
  const slots = $xeTree.$scopedSlots
@@ -1315,7 +1799,7 @@ export default /* define-vxe-component start */ defineVxeComponent({
1315
1799
 
1316
1800
  const { lazy, showRadio, showCheckbox, showLine, indent, iconOpen, iconClose, iconLoaded, showIcon } = props
1317
1801
  const { currentNode, selectRadioKey, updateExpandedFlag } = reactData
1318
- const { nodeMaps, treeExpandedMaps, treeExpandLazyLoadedMaps } = internalData
1802
+ const { afterTreeList, nodeMaps, treeExpandedMaps, treeExpandLazyLoadedMaps } = internalData
1319
1803
  const childrenField = $xeTree.computeChildrenField
1320
1804
  const titleField = $xeTree.computeTitleField
1321
1805
  const hasChildField = $xeTree.computeHasChildField
@@ -1324,15 +1808,13 @@ export default /* define-vxe-component start */ defineVxeComponent({
1324
1808
  const iconSlot = slots.icon
1325
1809
  const titleSlot = slots.title
1326
1810
  const extraSlot = slots.extra
1327
- const nodeid = $xeTree.getNodeId(node)
1328
1811
  const isExpand = updateExpandedFlag && treeExpandedMaps[nodeid]
1329
1812
  const nodeItem = nodeMaps[nodeid]
1330
1813
  const nodeValue = XEUtils.get(node, titleField)
1331
1814
 
1332
1815
  let isRadioChecked = false
1333
1816
  if (showRadio) {
1334
- // eslint-disable-next-line eqeqeq
1335
- isRadioChecked = nodeid == selectRadioKey
1817
+ isRadioChecked = nodeid === String(selectRadioKey)
1336
1818
  }
1337
1819
 
1338
1820
  let isCheckboxChecked = false
@@ -1348,27 +1830,11 @@ export default /* define-vxe-component start */ defineVxeComponent({
1348
1830
  hasLazyChilds = node[hasChildField]
1349
1831
  isLazyLoaded = !!nodeItem.treeLoaded
1350
1832
  }
1351
-
1352
- const childVns: VNode[] = []
1353
- if (hasChild && treeExpandedMaps[nodeid]) {
1354
- if (showLine) {
1355
- childVns.push(
1356
- h('div', {
1357
- key: 'line',
1358
- class: 'vxe-tree--node-child-line',
1359
- style: {
1360
- height: `calc(${nodeItem.lineCount} * var(--vxe-ui-tree-node-height) - var(--vxe-ui-tree-node-height) / 2)`,
1361
- left: `${(nodeItem.level + 1) * (indent || 1)}px`
1362
- }
1363
- })
1364
- )
1365
- }
1366
- childList.forEach(childItem => {
1367
- childVns.push($xeTree.renderNode(h, childItem))
1368
- })
1369
- }
1833
+ const prevNode = nodeItem.items[nodeItem.treeIndex - 1]
1834
+ const nParams = { node, isExpand }
1370
1835
 
1371
1836
  return h('div', {
1837
+ key: nodeid,
1372
1838
  class: ['vxe-tree--node-wrapper', `node--level-${nodeItem.level}`],
1373
1839
  attrs: {
1374
1840
  nodeid
@@ -1392,28 +1858,38 @@ export default /* define-vxe-component start */ defineVxeComponent({
1392
1858
  }
1393
1859
  }
1394
1860
  }, [
1395
- showIcon || showLine
1861
+ showLine
1396
1862
  ? h('div', {
1397
- class: 'vxe-tree--node-item-switcher'
1398
- }, showIcon && (lazy ? (isLazyLoaded ? hasChild : hasLazyChilds) : hasChild)
1399
- ? [
1400
- h('div', {
1401
- class: 'vxe-tree--node-item-icon',
1402
- on: {
1403
- click (evnt: MouseEvent) {
1404
- $xeTree.toggleExpandEvent(evnt, node)
1405
- }
1406
- }
1407
- }, iconSlot
1408
- ? iconSlot({ node, isExpand })
1409
- : [
1410
- h('i', {
1411
- class: isLazyLoading ? (iconLoaded || getIcon().TREE_NODE_LOADED) : (isExpand ? (iconOpen || getIcon().TREE_NODE_OPEN) : (iconClose || getIcon().TREE_NODE_CLOSE))
1412
- })
1413
- ])
1414
- ]
1415
- : [])
1863
+ class: 'vxe-tree--node-line-wrapper'
1864
+ }, [
1865
+ h('div', {
1866
+ class: 'vxe-tree--node-line',
1867
+ style: {
1868
+ height: `${$xeTree.getNodeId(afterTreeList[0]) === nodeid ? 1 : calcTreeLine($xeTree, node, prevNode)}px`
1869
+ }
1870
+ })
1871
+ ])
1416
1872
  : renderEmptyElement($xeTree),
1873
+ h('div', {
1874
+ class: 'vxe-tree--node-item-switcher'
1875
+ }, showIcon && (lazy ? (isLazyLoaded ? hasChild : hasLazyChilds) : hasChild)
1876
+ ? [
1877
+ h('div', {
1878
+ class: 'vxe-tree--node-item-icon',
1879
+ on: {
1880
+ click (evnt: MouseEvent) {
1881
+ $xeTree.toggleExpandEvent(evnt, node)
1882
+ }
1883
+ }
1884
+ }, iconSlot
1885
+ ? getSlotVNs(iconSlot(nParams))
1886
+ : [
1887
+ h('i', {
1888
+ class: isLazyLoading ? (iconLoaded || getIcon().TREE_NODE_LOADED) : (isExpand ? (iconOpen || getIcon().TREE_NODE_OPEN) : (iconClose || getIcon().TREE_NODE_CLOSE))
1889
+ })
1890
+ ])
1891
+ ]
1892
+ : []),
1417
1893
  $xeTree.renderRadio(h, node, nodeid, isRadioChecked),
1418
1894
  $xeTree.renderCheckbox(h, node, nodeid, isCheckboxChecked),
1419
1895
  h('div', {
@@ -1421,43 +1897,66 @@ export default /* define-vxe-component start */ defineVxeComponent({
1421
1897
  }, [
1422
1898
  h('div', {
1423
1899
  class: 'vxe-tree--node-item-title'
1424
- }, titleSlot ? getSlotVNs(titleSlot({ node, isExpand })) : `${nodeValue}`),
1900
+ }, titleSlot ? getSlotVNs(titleSlot(nParams)) : `${nodeValue}`),
1425
1901
  extraSlot
1426
1902
  ? h('div', {
1427
1903
  class: 'vxe-tree--node-item-extra'
1428
- }, getSlotVNs(extraSlot({ node, isExpand })))
1904
+ }, getSlotVNs(extraSlot(nParams)))
1429
1905
  : renderEmptyElement($xeTree)
1430
1906
  ])
1431
- ]),
1432
- hasChild && treeExpandedMaps[nodeid]
1433
- ? h('div', {
1434
- class: 'vxe-tree--node-child-wrapper'
1435
- }, childVns)
1436
- : renderEmptyElement($xeTree)
1907
+ ])
1437
1908
  ])
1438
1909
  },
1439
- renderNodeList (h: CreateElement) {
1910
+ renderList (h: CreateElement, treeList: any[]) {
1440
1911
  const $xeTree = this
1441
- const reactData = $xeTree.reactData
1912
+ const props = $xeTree
1913
+ const internalData = $xeTree.internalData
1442
1914
 
1443
- const { treeList } = reactData
1444
- return h('div', {
1445
- class: 'vxe-tree--node-list-wrapper'
1446
- }, treeList.map(node => $xeTree.renderNode(h, node)))
1915
+ const { transform } = props
1916
+ const { treeExpandedMaps } = internalData
1917
+ const childrenField = $xeTree.computeChildrenField
1918
+ if (!treeList.length) {
1919
+ return [
1920
+ h('div', {
1921
+ class: 'vxe-tree--empty-placeholder'
1922
+ }, getI18n('vxe.tree.searchEmpty'))
1923
+ ]
1924
+ }
1925
+ const nodeVNs: VNode[] = []
1926
+ treeList.forEach(transform
1927
+ ? (node) => {
1928
+ const nodeid = $xeTree.getNodeId(node)
1929
+ nodeVNs.push($xeTree.renderNode(h, node, nodeid))
1930
+ }
1931
+ : (node) => {
1932
+ const nodeid = $xeTree.getNodeId(node)
1933
+ nodeVNs.push($xeTree.renderNode(h, node, nodeid))
1934
+ const childList: any[] = XEUtils.get(node, childrenField)
1935
+ const hasChild = childList && childList.length
1936
+ if (hasChild && treeExpandedMaps[nodeid]) {
1937
+ nodeVNs.push(...$xeTree.renderList(h, childList))
1938
+ }
1939
+ })
1940
+ return nodeVNs
1447
1941
  },
1448
1942
  renderVN (h: CreateElement): VNode {
1449
1943
  const $xeTree = this
1450
1944
  const props = $xeTree
1451
1945
  const slots = $xeTree.$scopedSlots
1946
+ const reactData = $xeTree.reactData
1452
1947
 
1453
1948
  const { loading, trigger, showLine } = props
1949
+ const { bodyHeight, topSpaceHeight, treeList } = reactData
1454
1950
  const vSize = $xeTree.computeSize
1455
1951
  const radioOpts = $xeTree.computeRadioOpts
1456
1952
  const checkboxOpts = $xeTree.computeCheckboxOpts
1457
- const treeStyle = $xeTree.computeTreeStyle
1458
1953
  const loadingOpts = $xeTree.computeLoadingOpts
1459
1954
  const isRowHover = $xeTree.computeIsRowHover
1955
+ const treeStyle = $xeTree.computeTreeStyle
1460
1956
  const loadingSlot = slots.loading
1957
+ const headerSlot = slots.header
1958
+ const footerSlot = slots.footer
1959
+
1461
1960
  return h('div', {
1462
1961
  ref: 'refElem',
1463
1962
  class: ['vxe-tree', {
@@ -1468,10 +1967,42 @@ export default /* define-vxe-component start */ defineVxeComponent({
1468
1967
  'node--hover': isRowHover,
1469
1968
  'node--trigger': trigger === 'node',
1470
1969
  'is--loading': loading
1471
- }],
1472
- style: treeStyle
1970
+ }]
1473
1971
  }, [
1474
- $xeTree.renderNodeList(h),
1972
+ headerSlot
1973
+ ? h('div', {
1974
+ ref: 'refHeaderWrapperElem',
1975
+ class: 'vxe-tree--header-wrapper'
1976
+ }, headerSlot({ $tree: $xeTree }))
1977
+ : renderEmptyElement($xeTree),
1978
+ h('div', {
1979
+ ref: 'refVirtualWrapper',
1980
+ class: 'vxe-tree--node-list-wrapper',
1981
+ style: treeStyle,
1982
+ on: {
1983
+ scroll: $xeTree.scrollEvent
1984
+ }
1985
+ }, [
1986
+ h('div', {
1987
+ class: 'vxe-select--y-space',
1988
+ style: {
1989
+ height: bodyHeight ? `${bodyHeight}px` : ''
1990
+ }
1991
+ }),
1992
+ h('div', {
1993
+ ref: 'refVirtualBody',
1994
+ class: 'vxe-tree--node-list-body',
1995
+ style: {
1996
+ transform: `translateY(${topSpaceHeight}px)`
1997
+ }
1998
+ }, $xeTree.renderList(h, treeList))
1999
+ ]),
2000
+ footerSlot
2001
+ ? h('div', {
2002
+ ref: 'refFooterWrapperElem',
2003
+ class: 'vxe-tree--footer-wrapper'
2004
+ }, footerSlot({ $tree: $xeTree }))
2005
+ : renderEmptyElement($xeTree),
1475
2006
  /**
1476
2007
  * 加载中
1477
2008
  */
@@ -1495,7 +2026,7 @@ export default /* define-vxe-component start */ defineVxeComponent({
1495
2026
  data (val) {
1496
2027
  const $xeTree = this
1497
2028
 
1498
- $xeTree.loadTreeData(val || [])
2029
+ $xeTree.loadData(val || [])
1499
2030
  },
1500
2031
  checkNodeKey (val) {
1501
2032
  const $xeTree = this
@@ -1508,6 +2039,26 @@ export default /* define-vxe-component start */ defineVxeComponent({
1508
2039
  const props = $xeTree
1509
2040
 
1510
2041
  $xeTree.updateCheckboxChecked(props.checkNodeKeys || [])
2042
+ },
2043
+ filterValue () {
2044
+ const $xeTree = this
2045
+
2046
+ $xeTree.triggerSearchEvent(new Event('filter'))
2047
+ },
2048
+ height () {
2049
+ const $xeTree = this
2050
+
2051
+ $xeTree.recalculate()
2052
+ },
2053
+ minHeight () {
2054
+ const $xeTree = this
2055
+
2056
+ $xeTree.recalculate()
2057
+ },
2058
+ maxHeight () {
2059
+ const $xeTree = this
2060
+
2061
+ $xeTree.recalculate()
1511
2062
  }
1512
2063
  },
1513
2064
  created () {
@@ -1517,17 +2068,46 @@ export default /* define-vxe-component start */ defineVxeComponent({
1517
2068
 
1518
2069
  reactData.selectRadioKey = props.checkNodeKey || null
1519
2070
 
1520
- $xeTree.loadTreeData(props.data || [])
2071
+ $xeTree.loadData(props.data || [])
2072
+ },
2073
+ mounted () {
2074
+ const $xeTree = this
2075
+ const props = $xeTree
2076
+ const internalData = $xeTree.internalData
2077
+
2078
+ if (props.autoResize) {
2079
+ const el = $xeTree.$refs.refElem as HTMLDivElement
2080
+ const parentEl = $xeTree.getParentElem()
2081
+ const resizeObserver = globalResize.create(() => {
2082
+ if (props.autoResize) {
2083
+ $xeTree.recalculate()
2084
+ }
2085
+ })
2086
+ if (el) {
2087
+ resizeObserver.observe(el)
2088
+ }
2089
+ if (parentEl) {
2090
+ resizeObserver.observe(parentEl)
2091
+ }
2092
+ internalData.resizeObserver = resizeObserver
2093
+ }
2094
+
2095
+ globalEvents.on($xeTree, 'resize', $xeTree.handleGlobalResizeEvent)
1521
2096
  },
1522
2097
  beforeDestroy () {
1523
2098
  const $xeTree = this
1524
- const reactData = $xeTree.reactData
1525
2099
  const internalData = $xeTree.internalData
1526
2100
 
1527
- reactData.treeList = []
2101
+ const { resizeObserver } = internalData
2102
+ if (resizeObserver) {
2103
+ resizeObserver.disconnect()
2104
+ }
2105
+
1528
2106
  internalData.treeExpandedMaps = {}
1529
2107
  internalData.indeterminateRowMaps = {}
1530
2108
  internalData.nodeMaps = {}
2109
+
2110
+ globalEvents.off($xeTree, 'resize')
1531
2111
  },
1532
2112
  render (this: any, h) {
1533
2113
  return this.renderVN(h)