vxe-pc-ui 4.20.0 → 4.20.2

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 (128) hide show
  1. package/dist/all.esm.js +780 -173
  2. package/dist/style.css +1 -1
  3. package/dist/style.min.css +1 -1
  4. package/es/card/src/card.js +19 -4
  5. package/es/drawer/src/drawer.js +59 -15
  6. package/es/drawer/style.css +13 -6
  7. package/es/drawer/style.min.css +1 -1
  8. package/es/icon/style.css +1 -1
  9. package/es/language/fr-FR.js +29 -29
  10. package/es/layout-aside/src/layout-aside.js +10 -6
  11. package/es/layout-body/src/layout-body.js +21 -12
  12. package/es/list/src/list.js +118 -49
  13. package/es/list/style.css +25 -8
  14. package/es/list/style.min.css +1 -1
  15. package/es/menu/src/menu.js +2 -2
  16. package/es/modal/src/modal.js +56 -12
  17. package/es/modal/style.css +15 -4
  18. package/es/modal/style.min.css +1 -1
  19. package/es/scrollbar/src/scrollbar.js +73 -19
  20. package/es/style.css +1 -1
  21. package/es/style.min.css +1 -1
  22. package/es/tabs/src/tabs.js +21 -6
  23. package/es/tree/src/tree.js +410 -53
  24. package/es/tree/style.css +43 -0
  25. package/es/tree/style.min.css +1 -1
  26. package/es/ui/index.js +1 -1
  27. package/es/ui/src/log.js +1 -1
  28. package/es/ui/src/utils.js +3 -0
  29. package/es/vxe-drawer/style.css +13 -6
  30. package/es/vxe-drawer/style.min.css +1 -1
  31. package/es/vxe-list/style.css +25 -8
  32. package/es/vxe-list/style.min.css +1 -1
  33. package/es/vxe-modal/style.css +15 -4
  34. package/es/vxe-modal/style.min.css +1 -1
  35. package/es/vxe-tree/style.css +43 -0
  36. package/es/vxe-tree/style.min.css +1 -1
  37. package/lib/card/src/card.js +19 -4
  38. package/lib/card/src/card.min.js +1 -1
  39. package/lib/drawer/src/drawer.js +64 -11
  40. package/lib/drawer/src/drawer.min.js +1 -1
  41. package/lib/drawer/style/style.css +13 -6
  42. package/lib/drawer/style/style.min.css +1 -1
  43. package/lib/icon/style/style.css +1 -1
  44. package/lib/icon/style/style.min.css +1 -1
  45. package/lib/index.umd.js +887 -183
  46. package/lib/index.umd.min.js +1 -1
  47. package/lib/language/fr-FR.js +29 -29
  48. package/lib/language/fr-FR.min.js +1 -1
  49. package/lib/language/fr-FR.umd.js +29 -29
  50. package/lib/layout-aside/src/layout-aside.js +9 -8
  51. package/lib/layout-aside/src/layout-aside.min.js +1 -1
  52. package/lib/layout-body/src/layout-body.js +29 -22
  53. package/lib/layout-body/src/layout-body.min.js +1 -1
  54. package/lib/list/src/list.js +110 -47
  55. package/lib/list/src/list.min.js +1 -1
  56. package/lib/list/style/style.css +25 -8
  57. package/lib/list/style/style.min.css +1 -1
  58. package/lib/menu/src/menu.js +1 -1
  59. package/lib/menu/src/menu.min.js +1 -1
  60. package/lib/modal/src/modal.js +61 -10
  61. package/lib/modal/src/modal.min.js +1 -1
  62. package/lib/modal/style/style.css +15 -4
  63. package/lib/modal/style/style.min.css +1 -1
  64. package/lib/scrollbar/src/scrollbar.js +81 -17
  65. package/lib/scrollbar/src/scrollbar.min.js +1 -1
  66. package/lib/style.css +1 -1
  67. package/lib/style.min.css +1 -1
  68. package/lib/tabs/src/tabs.js +23 -11
  69. package/lib/tabs/src/tabs.min.js +1 -1
  70. package/lib/tree/src/tree.js +412 -50
  71. package/lib/tree/src/tree.min.js +1 -1
  72. package/lib/tree/style/style.css +43 -0
  73. package/lib/tree/style/style.min.css +1 -1
  74. package/lib/ui/index.js +1 -1
  75. package/lib/ui/index.min.js +1 -1
  76. package/lib/ui/src/log.js +1 -1
  77. package/lib/ui/src/log.min.js +1 -1
  78. package/lib/ui/src/utils.js +4 -0
  79. package/lib/ui/src/utils.min.js +1 -1
  80. package/lib/vxe-drawer/style/style.css +13 -6
  81. package/lib/vxe-drawer/style/style.min.css +1 -1
  82. package/lib/vxe-list/style/style.css +25 -8
  83. package/lib/vxe-list/style/style.min.css +1 -1
  84. package/lib/vxe-modal/style/style.css +15 -4
  85. package/lib/vxe-modal/style/style.min.css +1 -1
  86. package/lib/vxe-tree/style/style.css +43 -0
  87. package/lib/vxe-tree/style/style.min.css +1 -1
  88. package/package.json +2 -2
  89. package/packages/card/src/card.ts +20 -4
  90. package/packages/drawer/src/drawer.ts +73 -16
  91. package/packages/language/fr-FR.ts +903 -903
  92. package/packages/layout-aside/src/layout-aside.ts +10 -6
  93. package/packages/layout-body/src/layout-body.ts +25 -15
  94. package/packages/list/src/list.ts +130 -55
  95. package/packages/menu/src/menu.ts +2 -2
  96. package/packages/modal/src/modal.ts +71 -14
  97. package/packages/scrollbar/src/scrollbar.ts +79 -18
  98. package/packages/tabs/src/tabs.ts +21 -7
  99. package/packages/tree/src/tree.ts +452 -62
  100. package/packages/ui/src/utils.ts +4 -0
  101. package/styles/components/drawer.scss +13 -6
  102. package/styles/components/list.scss +35 -10
  103. package/styles/components/modal.scss +12 -4
  104. package/styles/components/tree.scss +76 -0
  105. package/types/components/card.d.ts +10 -1
  106. package/types/components/drawer.d.ts +20 -0
  107. package/types/components/gantt-module/gantt-view.d.ts +24 -1
  108. package/types/components/gantt.d.ts +2 -0
  109. package/types/components/layout-aside.d.ts +10 -1
  110. package/types/components/layout-body.d.ts +10 -1
  111. package/types/components/list.d.ts +13 -2
  112. package/types/components/modal.d.ts +20 -0
  113. package/types/components/scrollbar.d.ts +17 -2
  114. package/types/components/table.d.ts +80 -6
  115. package/types/components/tabs.d.ts +10 -1
  116. package/types/components/tree.d.ts +35 -2
  117. /package/es/icon/{iconfont.1791880413927.ttf → iconfont.1792034967421.ttf} +0 -0
  118. /package/es/icon/{iconfont.1791880413927.woff → iconfont.1792034967421.woff} +0 -0
  119. /package/es/icon/{iconfont.1791880413927.woff2 → iconfont.1792034967421.woff2} +0 -0
  120. /package/es/{iconfont.1791880413927.ttf → iconfont.1792034967421.ttf} +0 -0
  121. /package/es/{iconfont.1791880413927.woff → iconfont.1792034967421.woff} +0 -0
  122. /package/es/{iconfont.1791880413927.woff2 → iconfont.1792034967421.woff2} +0 -0
  123. /package/lib/icon/style/{iconfont.1791880413927.ttf → iconfont.1792034967421.ttf} +0 -0
  124. /package/lib/icon/style/{iconfont.1791880413927.woff → iconfont.1792034967421.woff} +0 -0
  125. /package/lib/icon/style/{iconfont.1791880413927.woff2 → iconfont.1792034967421.woff2} +0 -0
  126. /package/lib/{iconfont.1791880413927.ttf → iconfont.1792034967421.ttf} +0 -0
  127. /package/lib/{iconfont.1791880413927.woff → iconfont.1792034967421.woff} +0 -0
  128. /package/lib/{iconfont.1791880413927.woff2 → iconfont.1792034967421.woff2} +0 -0
@@ -3,7 +3,7 @@ import { defineVxeComponent } from '../../ui/src/comp';
3
3
  import { createEvent, getConfig, getIcon, globalEvents, permission, useSize, renderEmptyElement } from '../../ui';
4
4
  import { getSlotVNs } from '../../ui/src/vn';
5
5
  import { toCssUnit, addClass, removeClass } from '../../ui/src/dom';
6
- import { isEnableConf } from '../../ui/src/utils';
6
+ import { getDefaultConfig, isEnableConf } from '../../ui/src/utils';
7
7
  import { createComponentLog } from '../../ui/src/log';
8
8
  import XEUtils from 'xe-utils';
9
9
  import VxeLoadingComponent from '../../loading';
@@ -50,7 +50,7 @@ export default defineVxeComponent({
50
50
  },
51
51
  useScrollbar: {
52
52
  type: Boolean,
53
- default: () => getConfig().tabs.useScrollbar
53
+ default: () => getDefaultConfig(getConfig().tabs.useScrollbar, getConfig().useScrollbar)
54
54
  },
55
55
  scrollbarConfig: Object,
56
56
  // 已废弃
@@ -151,6 +151,22 @@ export default defineVxeComponent({
151
151
  const computeScrollbarOpts = computed(() => {
152
152
  return Object.assign({}, getConfig().tabs.scrollbarConfig, props.scrollbarConfig);
153
153
  });
154
+ const computeScrollbarProps = computed(() => {
155
+ const scrollbarOpts = computeScrollbarOpts.value;
156
+ const { viewClassName, viewInnerClassName } = scrollbarOpts;
157
+ return {
158
+ width: scrollbarOpts.width,
159
+ height: scrollbarOpts.height,
160
+ autoHide: scrollbarOpts.autoHide,
161
+ visible: scrollbarOpts.visible,
162
+ xConfig: scrollbarOpts.xConfig,
163
+ yConfig: scrollbarOpts.yConfig,
164
+ className: scrollbarOpts.className,
165
+ viewAttrs: scrollbarOpts.viewAttrs,
166
+ viewClassName: 'vxe-tabs-pane--scrollbar-item-view' + (viewClassName ? (' ' + viewClassName) : ''),
167
+ viewInnerClassName: 'vxe-tabs-pane--scrollbar-item-inner' + (viewClassName ? (' ' + viewInnerClassName) : '')
168
+ };
169
+ });
154
170
  const computeMaps = {};
155
171
  const $xeTabs = {
156
172
  xID,
@@ -730,13 +746,12 @@ export default defineVxeComponent({
730
746
  const { initNames, activeName } = reactData;
731
747
  const { name, slots } = item;
732
748
  const defaultSlot = slots ? slots.default : null;
733
- const scrollbarOpts = computeScrollbarOpts.value;
734
- const { viewClassName, viewInnerClassName } = scrollbarOpts;
749
+ const scrollbarProps = computeScrollbarProps.value;
735
750
  if (name && initNames.includes(name)) {
736
751
  return useScrollbar
737
- ? h(VxeScrollbarComponent, Object.assign(Object.assign({ key: `${name}`, class: ['vxe-tabs-pane--scrollbar-item', {
752
+ ? h(VxeScrollbarComponent, Object.assign({ key: `${name}`, class: ['vxe-tabs-pane--scrollbar-item', {
738
753
  'is--visible': activeName === name
739
- }] }, scrollbarOpts), { viewClassName: 'vxe-tabs-pane--scrollbar-item-view' + (viewClassName ? (' ' + viewClassName) : ''), viewInnerClassName: 'vxe-tabs-pane--scrollbar-item-inner' + (viewClassName ? (' ' + viewInnerClassName) : '') }), {
754
+ }] }, scrollbarProps), {
740
755
  default: () => defaultSlot ? callSlot(defaultSlot, { name }) : []
741
756
  })
742
757
  : h('div', {
@@ -1,14 +1,15 @@
1
1
  import { ref, h, reactive, computed, watch, onBeforeUnmount, nextTick, onMounted, provide } from 'vue';
2
2
  import { defineVxeComponent } from '../../ui/src/comp';
3
- import { VxeUI, createEvent, useSize, globalEvents, globalResize, renderEmptyElement } from '../../ui';
3
+ import { VxeUI, domUtils, createEvent, useSize, globalEvents, globalResize, renderEmptyElement } from '../../ui';
4
4
  import { calcTreeLine, getItemCacheObj } from './util';
5
5
  import { createComponentLog } from '../../ui/src/log';
6
6
  import { getCrossTreeDragNodeInfo } from './store';
7
7
  import XEUtils from 'xe-utils';
8
8
  import { getSlotVNs } from '../../ui/src/vn';
9
9
  import { toCssUnit, isScale, getPaddingTopBottomSize, addClass, removeClass, getTpImg, hasControlKey, getEventTargetNode, hasClass } from '../../ui/src/dom';
10
- import { isEnableConf, enModelValue, deModelValue, getText } from '../../ui/src/utils';
10
+ import { isEnableConf, enModelValue, deModelValue, getText, getDefaultConfig } from '../../ui/src/utils';
11
11
  import { moveRowAnimateToTb, clearRowAnimate } from '../../ui/src/anime';
12
+ import { getThumbOffsetSize, getThumbSize, getScrollFromClick, getScrollFromDrag } from '../../scrollbar/src/util';
12
13
  import VxeLoadingComponent from '../../loading';
13
14
  import VxeTooltipComponent from '../../tooltip';
14
15
  const { warnLog, errLog } = createComponentLog('tree');
@@ -19,6 +20,34 @@ const { menus, getConfig, getI18n, getIcon } = VxeUI;
19
20
  function getNodeUniqueId() {
20
21
  return XEUtils.uniqueId('node_');
21
22
  }
23
+ function createReactData() {
24
+ return {
25
+ parentHeight: 0,
26
+ customHeight: 0,
27
+ customMinHeight: 0,
28
+ customMaxHeight: 0,
29
+ currentNode: null,
30
+ scrollYLoad: false,
31
+ bodyHeight: 0,
32
+ topSpaceHeight: 0,
33
+ selectRadioKey: null,
34
+ treeList: [],
35
+ updateExpandedFlag: 1,
36
+ updateCheckboxFlag: 1,
37
+ // 滚动条
38
+ yThumbHeight: 0,
39
+ xThumbWidth: 0,
40
+ insertNodeFlag: 1,
41
+ removeNodeFlag: 1,
42
+ dragNode: null,
43
+ dragTipText: '',
44
+ isCrossDragNode: false,
45
+ tooltipStore: {
46
+ visible: false,
47
+ node: null
48
+ }
49
+ };
50
+ }
22
51
  function createInternalData() {
23
52
  return {
24
53
  // initialized: false,
@@ -31,8 +60,15 @@ function createInternalData() {
31
60
  indeterminateNodeMaps: {},
32
61
  treeExpandedMaps: {},
33
62
  treeExpandLazyLoadedMaps: {},
34
- lastScrollLeft: 0,
63
+ // resizeObserver: undefined,
64
+ // 滚动条
65
+ // scrollObserver: undefined,
66
+ // isThumbDrag: false,
67
+ thumbDragOffset: 0,
68
+ yThumbTop: 0,
69
+ xThumbLeft: 0,
35
70
  lastScrollTop: 0,
71
+ lastScrollLeft: 0,
36
72
  scrollYStore: {
37
73
  startIndex: 0,
38
74
  endIndex: 0,
@@ -49,31 +85,6 @@ function createInternalData() {
49
85
  // hpTimeout: undefined
50
86
  };
51
87
  }
52
- function createReactData() {
53
- return {
54
- parentHeight: 0,
55
- customHeight: 0,
56
- customMinHeight: 0,
57
- customMaxHeight: 0,
58
- currentNode: null,
59
- scrollYLoad: false,
60
- bodyHeight: 0,
61
- topSpaceHeight: 0,
62
- selectRadioKey: null,
63
- treeList: [],
64
- updateExpandedFlag: 1,
65
- updateCheckboxFlag: 1,
66
- insertNodeFlag: 1,
67
- removeNodeFlag: 1,
68
- dragNode: null,
69
- dragTipText: '',
70
- isCrossDragNode: false,
71
- tooltipStore: {
72
- visible: false,
73
- node: null
74
- }
75
- };
76
- }
77
88
  let crossTreeDragNodeObj = null;
78
89
  export default defineVxeComponent({
79
90
  name: 'VxeTree',
@@ -204,7 +215,12 @@ export default defineVxeComponent({
204
215
  type: String,
205
216
  default: () => getConfig().tree.size || getConfig().size
206
217
  },
207
- virtualYConfig: Object
218
+ virtualYConfig: Object,
219
+ useScrollbar: {
220
+ type: Boolean,
221
+ default: () => getDefaultConfig(getConfig().tree.useScrollbar, getConfig().useScrollbar)
222
+ },
223
+ scrollbarConfig: Object
208
224
  },
209
225
  emits: [
210
226
  'update:modelValue',
@@ -236,6 +252,10 @@ export default defineVxeComponent({
236
252
  const refFooterWrapperElem = ref();
237
253
  const refVirtualWrapper = ref();
238
254
  const refVirtualBody = ref();
255
+ const refTrackXElem = ref();
256
+ const refTrackYElem = ref();
257
+ const refThumbXElem = ref();
258
+ const refThumbYElem = ref();
239
259
  const refDragNodeLineElem = ref();
240
260
  const refDragTipElem = ref();
241
261
  const refTooltip = ref();
@@ -307,6 +327,16 @@ export default defineVxeComponent({
307
327
  const computeMenuOpts = computed(() => {
308
328
  return Object.assign({}, getConfig().tree.menuConfig, props.menuConfig);
309
329
  });
330
+ const computeWrapperStyles = computed(() => {
331
+ const barWidth = computeScrollYWidth.value;
332
+ const barHeight = computeScrollXHeight.value;
333
+ const stys = {};
334
+ if (barWidth || barHeight) {
335
+ stys['--vxe-ui-scrollbar-y-width'] = toCssUnit(barWidth || barHeight);
336
+ stys['--vxe-ui-scrollbar-x-height'] = toCssUnit(barHeight || barWidth);
337
+ }
338
+ return stys;
339
+ });
310
340
  const computeTreeStyle = computed(() => {
311
341
  const { indent } = props;
312
342
  const { customHeight, customMinHeight, customMaxHeight } = reactData;
@@ -339,6 +369,74 @@ export default defineVxeComponent({
339
369
  const computeFilterOpts = computed(() => {
340
370
  return Object.assign({}, getConfig().tree.filterConfig, props.filterConfig);
341
371
  });
372
+ const computeScrollbarOpts = computed(() => {
373
+ return Object.assign({}, getConfig().tree.scrollbarConfig, props.scrollbarConfig);
374
+ });
375
+ const computeScrollbarXOpts = computed(() => {
376
+ const scrollbarOpts = computeScrollbarOpts.value;
377
+ return Object.assign({}, getConfig().scrollbar.xConfig, scrollbarOpts.xConfig, {
378
+ visible: false
379
+ });
380
+ });
381
+ const computeScrollbarYOpts = computed(() => {
382
+ const scrollbarOpts = computeScrollbarOpts.value;
383
+ return Object.assign({}, getConfig().scrollbar.yConfig, scrollbarOpts.yConfig);
384
+ });
385
+ const computeScrollXHeight = computed(() => {
386
+ const scrollbarOpts = computeScrollbarOpts.value;
387
+ const scrollbarXOpts = computeScrollbarXOpts.value;
388
+ return getDefaultConfig(getDefaultConfig(scrollbarXOpts.height, scrollbarOpts.height), getConfig().scrollbar.height);
389
+ });
390
+ const computeScrollYWidth = computed(() => {
391
+ const scrollbarOpts = computeScrollbarOpts.value;
392
+ const scrollbarYOpts = computeScrollbarYOpts.value;
393
+ return getDefaultConfig(getDefaultConfig(scrollbarYOpts.width, scrollbarOpts.width), getConfig().scrollbar.width);
394
+ });
395
+ const computeScrollXVisible = computed(() => {
396
+ const scrollbarOpts = computeScrollbarOpts.value;
397
+ const scrollbarXOpts = computeScrollbarXOpts.value;
398
+ return getDefaultConfig(scrollbarXOpts.visible, scrollbarOpts.visible);
399
+ });
400
+ const computeScrollYVisible = computed(() => {
401
+ const scrollbarOpts = computeScrollbarOpts.value;
402
+ const scrollbarYOpts = computeScrollbarYOpts.value;
403
+ return getDefaultConfig(scrollbarYOpts.visible, scrollbarOpts.visible);
404
+ });
405
+ const computeScrollXAutoHide = computed(() => {
406
+ const scrollbarOpts = computeScrollbarOpts.value;
407
+ const scrollbarXOpts = computeScrollbarXOpts.value;
408
+ return getDefaultConfig(getDefaultConfig(scrollbarXOpts.autoHide, scrollbarOpts.autoHide), getConfig().scrollbar.autoHide);
409
+ });
410
+ const computeScrollYAutoHide = computed(() => {
411
+ const scrollbarOpts = computeScrollbarOpts.value;
412
+ const scrollbarYOpts = computeScrollbarYOpts.value;
413
+ return getDefaultConfig(getDefaultConfig(scrollbarYOpts.autoHide, scrollbarOpts.autoHide), getConfig().scrollbar.autoHide);
414
+ });
415
+ const computeScrollbarWrapperClss = computed(() => {
416
+ const { yThumbHeight, xThumbWidth } = reactData;
417
+ const scrollbarXToTop = computeScrollbarXToTop.value;
418
+ const scrollbarYToLeft = computeScrollbarYToLeft.value;
419
+ const scrollXVisible = computeScrollXVisible.value;
420
+ const scrollYVisible = computeScrollYVisible.value;
421
+ return domUtils.buildClass([
422
+ 'vxe-scrollbar is--virtual',
423
+ `ov-x--${scrollXVisible === false ? 'hidden' : 'visible'}`,
424
+ `ov-y--${scrollYVisible === false ? 'hidden' : 'visible'}`,
425
+ `sx-pos--${scrollbarXToTop ? 'top' : 'bottom'}`,
426
+ `sy-pos--${scrollbarYToLeft ? 'left' : 'right'}`
427
+ ], {
428
+ 'overflow-y': yThumbHeight,
429
+ 'overflow-x': xThumbWidth
430
+ });
431
+ });
432
+ const computeScrollbarXToTop = computed(() => {
433
+ const scrollbarXOpts = computeScrollbarXOpts.value;
434
+ return scrollbarXOpts.position === 'top';
435
+ });
436
+ const computeScrollbarYToLeft = computed(() => {
437
+ const scrollbarYOpts = computeScrollbarYOpts.value;
438
+ return scrollbarYOpts.position === 'left';
439
+ });
342
440
  const computeMaps = {
343
441
  computeKeyField,
344
442
  computeParentField,
@@ -856,6 +954,10 @@ export default defineVxeComponent({
856
954
  }
857
955
  });
858
956
  };
957
+ const updateScrollbar = () => {
958
+ updateThumbSize();
959
+ updateThumbOffset();
960
+ };
859
961
  /**
860
962
  * 重新计算列表
861
963
  */
@@ -877,6 +979,7 @@ export default defineVxeComponent({
877
979
  const parentPaddingSize = getPaddingTopBottomSize(parentEl);
878
980
  reactData.parentHeight = Math.max(headHeight + footHeight + rowHeight, parentEl.clientHeight - parentPaddingSize - headHeight - footHeight);
879
981
  }
982
+ updateScrollbar();
880
983
  updateHeight();
881
984
  return computeScrollLoad().then(() => {
882
985
  updateHeight();
@@ -910,6 +1013,7 @@ export default defineVxeComponent({
910
1013
  const scrollLeft = scrollBodyElem.scrollLeft;
911
1014
  const isX = scrollLeft !== internalData.lastScrollLeft;
912
1015
  const isY = scrollTop !== internalData.lastScrollTop;
1016
+ updateThumbOffset();
913
1017
  internalData.lastScrollTop = scrollTop;
914
1018
  internalData.lastScrollLeft = scrollLeft;
915
1019
  if (reactData.scrollYLoad) {
@@ -1457,13 +1561,6 @@ export default defineVxeComponent({
1457
1561
  emitRadioMode(value);
1458
1562
  dispatchEvent('radio-change', { node, value, checked: isChecked }, evnt);
1459
1563
  };
1460
- const handleGlobalResizeEvent = () => {
1461
- const el = refElem.value;
1462
- if (!el || !el.clientWidth) {
1463
- return;
1464
- }
1465
- recalculate();
1466
- };
1467
1564
  const insertTreeNode = (newRecords, isAppend) => {
1468
1565
  const { treeFullData, nodeMaps } = internalData;
1469
1566
  const keyField = computeKeyField.value;
@@ -2899,6 +2996,162 @@ export default defineVxeComponent({
2899
2996
  hideDropTip();
2900
2997
  }
2901
2998
  };
2999
+ const updateThumbSize = () => {
3000
+ const viewEl = refVirtualWrapper.value;
3001
+ if (!viewEl) {
3002
+ return;
3003
+ }
3004
+ if (!viewEl.clientHeight || !viewEl.clientHeight) {
3005
+ return;
3006
+ }
3007
+ const trackXEl = refTrackXElem.value;
3008
+ const xThumbWidth = trackXEl ? getThumbSize(viewEl.clientWidth, viewEl.scrollWidth, trackXEl.clientWidth) : 0;
3009
+ const thumbXElem = refThumbXElem.value;
3010
+ if (thumbXElem) {
3011
+ thumbXElem.style.width = xThumbWidth + 'px';
3012
+ }
3013
+ reactData.xThumbWidth = xThumbWidth;
3014
+ const trackYEl = refTrackYElem.value;
3015
+ const yThumbHeight = trackYEl ? getThumbSize(viewEl.clientHeight, viewEl.scrollHeight, trackYEl.clientHeight) : 0;
3016
+ const thumbYElem = refThumbYElem.value;
3017
+ if (thumbYElem) {
3018
+ thumbYElem.style.height = yThumbHeight + 'px';
3019
+ }
3020
+ reactData.yThumbHeight = yThumbHeight;
3021
+ };
3022
+ const updateThumbOffset = () => {
3023
+ const viewEl = refVirtualWrapper.value;
3024
+ if (!viewEl) {
3025
+ return;
3026
+ }
3027
+ if (!viewEl.clientHeight || !viewEl.clientHeight) {
3028
+ return;
3029
+ }
3030
+ const { xThumbWidth, yThumbHeight } = reactData;
3031
+ const trackXEl = refTrackXElem.value;
3032
+ const thumbXElem = refThumbXElem.value;
3033
+ const xThumbLeft = trackXEl && xThumbWidth ? getThumbOffsetSize(viewEl.scrollLeft, viewEl.clientWidth, viewEl.scrollWidth, trackXEl.clientWidth, xThumbWidth) : 0;
3034
+ internalData.xThumbLeft = xThumbLeft;
3035
+ if (thumbXElem && xThumbWidth) {
3036
+ thumbXElem.style.width = xThumbWidth + 'px';
3037
+ thumbXElem.style.transform = `translateX(${xThumbLeft}px)`;
3038
+ }
3039
+ const trackYEl = refTrackYElem.value;
3040
+ const thumbYElem = refThumbYElem.value;
3041
+ const yThumbTop = trackYEl && yThumbHeight ? getThumbOffsetSize(viewEl.scrollTop, viewEl.clientHeight, viewEl.scrollHeight, trackYEl.clientHeight, yThumbHeight) : 0;
3042
+ internalData.yThumbTop = yThumbTop;
3043
+ if (thumbYElem && yThumbHeight) {
3044
+ thumbYElem.style.height = yThumbHeight + 'px';
3045
+ thumbYElem.style.transform = `translateY(${yThumbTop}px)`;
3046
+ }
3047
+ };
3048
+ const clickTrackXEvent = (evnt) => {
3049
+ const trackEl = evnt.currentTarget;
3050
+ if (trackEl !== evnt.target) {
3051
+ return;
3052
+ }
3053
+ const viewEl = refVirtualWrapper.value;
3054
+ if (!viewEl) {
3055
+ return;
3056
+ }
3057
+ const { xThumbWidth } = reactData;
3058
+ const trackRect = trackEl.getBoundingClientRect();
3059
+ viewEl.scrollTo({
3060
+ left: getScrollFromClick(evnt.clientX - trackRect.left, viewEl.clientWidth, viewEl.scrollWidth, trackEl.clientWidth, xThumbWidth),
3061
+ behavior: 'auto'
3062
+ });
3063
+ };
3064
+ const clickTrackYEvent = (evnt) => {
3065
+ const trackEl = evnt.currentTarget;
3066
+ if (trackEl !== evnt.target) {
3067
+ return;
3068
+ }
3069
+ const viewEl = refVirtualWrapper.value;
3070
+ if (!viewEl) {
3071
+ return;
3072
+ }
3073
+ const { yThumbHeight } = reactData;
3074
+ const trackRect = trackEl.getBoundingClientRect();
3075
+ viewEl.scrollTo({
3076
+ top: getScrollFromClick(evnt.clientY - trackRect.top, viewEl.clientHeight, viewEl.scrollHeight, trackEl.clientHeight, yThumbHeight),
3077
+ behavior: 'auto'
3078
+ });
3079
+ };
3080
+ const pointerdownThumbXEvent = (evnt) => {
3081
+ const thumbEl = evnt.currentTarget;
3082
+ internalData.isThumbDrag = true;
3083
+ thumbEl.setPointerCapture(evnt.pointerId);
3084
+ const viewEl = refVirtualWrapper.value;
3085
+ if (!viewEl) {
3086
+ return;
3087
+ }
3088
+ const { xThumbWidth } = reactData;
3089
+ const trackEl = thumbEl.parentElement;
3090
+ const trackRect = trackEl.getBoundingClientRect();
3091
+ const pointerPosition = evnt.clientX - trackRect.left;
3092
+ // 记录 thumb 的偏移
3093
+ const thumbOffset = getThumbOffsetSize(viewEl.scrollLeft, viewEl.clientWidth, viewEl.scrollWidth, trackEl.clientWidth, xThumbWidth);
3094
+ internalData.thumbDragOffset = pointerPosition - thumbOffset;
3095
+ };
3096
+ const pointermoveThumbXEvent = (evnt) => {
3097
+ const thumbEl = evnt.currentTarget;
3098
+ if (!thumbEl.hasPointerCapture(evnt.pointerId)) {
3099
+ return;
3100
+ }
3101
+ const { isThumbDrag, thumbDragOffset } = internalData;
3102
+ if (isThumbDrag) {
3103
+ const viewEl = refVirtualWrapper.value;
3104
+ if (!viewEl) {
3105
+ return;
3106
+ }
3107
+ const { xThumbWidth } = reactData;
3108
+ const thumbEl = evnt.currentTarget;
3109
+ const trackEl = thumbEl.parentElement;
3110
+ const trackRect = trackEl.getBoundingClientRect();
3111
+ // 更新偏移
3112
+ viewEl.scrollLeft = getScrollFromDrag(evnt.clientX - trackRect.left, thumbDragOffset, viewEl.clientWidth, viewEl.scrollWidth, trackEl.clientWidth, xThumbWidth);
3113
+ }
3114
+ };
3115
+ const cleatPointerThumbEvent = (evnt) => {
3116
+ const thumbEl = evnt.currentTarget;
3117
+ thumbEl.releasePointerCapture(evnt.pointerId);
3118
+ internalData.isThumbDrag = false;
3119
+ };
3120
+ const pointerdownThumbYEvent = (evnt) => {
3121
+ const thumbEl = evnt.currentTarget;
3122
+ internalData.isThumbDrag = true;
3123
+ thumbEl.setPointerCapture(evnt.pointerId);
3124
+ const viewEl = refVirtualWrapper.value;
3125
+ if (!viewEl) {
3126
+ return;
3127
+ }
3128
+ const { yThumbHeight } = reactData;
3129
+ const trackEl = thumbEl.parentElement;
3130
+ const trackRect = trackEl.getBoundingClientRect();
3131
+ const pointerPosition = evnt.clientY - trackRect.top;
3132
+ // 记录 thumb 的偏移
3133
+ const thumbOffset = getThumbOffsetSize(viewEl.scrollTop, viewEl.clientHeight, viewEl.scrollHeight, trackEl.clientHeight, yThumbHeight);
3134
+ internalData.thumbDragOffset = pointerPosition - thumbOffset;
3135
+ };
3136
+ const pointermoveThumbYEvent = (evnt) => {
3137
+ const thumbEl = evnt.currentTarget;
3138
+ if (!thumbEl.hasPointerCapture(evnt.pointerId)) {
3139
+ return;
3140
+ }
3141
+ const { isThumbDrag, thumbDragOffset } = internalData;
3142
+ if (isThumbDrag) {
3143
+ const viewEl = refVirtualWrapper.value;
3144
+ if (!viewEl) {
3145
+ return;
3146
+ }
3147
+ const { yThumbHeight } = reactData;
3148
+ const thumbEl = evnt.currentTarget;
3149
+ const trackEl = thumbEl.parentElement;
3150
+ const trackRect = trackEl.getBoundingClientRect();
3151
+ // 更新偏移
3152
+ viewEl.scrollTop = getScrollFromDrag(evnt.clientY - trackRect.top, thumbDragOffset, viewEl.clientHeight, viewEl.scrollHeight, trackEl.clientHeight, yThumbHeight);
3153
+ }
3154
+ };
2902
3155
  Object.assign($xeTree, treeMethods, treePrivateMethods);
2903
3156
  const renderDragIcon = (node, nodeid) => {
2904
3157
  const { drag, transform } = props;
@@ -3208,13 +3461,14 @@ export default defineVxeComponent({
3208
3461
  return renderEmptyElement($xeTree);
3209
3462
  };
3210
3463
  const renderVN = () => {
3211
- const { loading, trigger, showLine } = props;
3212
- const { bodyHeight, topSpaceHeight, treeList, tooltipStore } = reactData;
3464
+ const { loading, trigger, showLine, useScrollbar } = props;
3465
+ const { bodyHeight, topSpaceHeight, treeList, tooltipStore, xThumbWidth, yThumbHeight } = reactData;
3213
3466
  const vSize = computeSize.value;
3214
3467
  const radioOpts = computeRadioOpts.value;
3215
3468
  const checkboxOpts = computeCheckboxOpts.value;
3216
3469
  const loadingOpts = computeLoadingOpts.value;
3217
3470
  const isNodeHover = computeIsNodeHover.value;
3471
+ const wrapperStyles = computeWrapperStyles.value;
3218
3472
  const treeStyle = computeTreeStyle.value;
3219
3473
  const dragOpts = computeDragOpts.value;
3220
3474
  const tooltipOpts = computeTooltipOpts.value;
@@ -3222,19 +3476,40 @@ export default defineVxeComponent({
3222
3476
  const headerSlot = slots.header;
3223
3477
  const footerSlot = slots.footer;
3224
3478
  const tooltipSlot = slots.tooltip;
3479
+ const scrollbarOpts = computeScrollbarOpts.value;
3480
+ const scrollXVisible = computeScrollXVisible.value;
3481
+ const scrollYVisible = computeScrollYVisible.value;
3482
+ const scrollbarXToTop = computeScrollbarXToTop.value;
3483
+ const scrollbarYToLeft = computeScrollbarYToLeft.value;
3484
+ const scrollXAutoHide = computeScrollXAutoHide.value;
3485
+ const scrollYAutoHide = computeScrollYAutoHide.value;
3486
+ const scrollbarWrapperClss = computeScrollbarWrapperClss.value;
3225
3487
  const teOns = {};
3226
3488
  if (dragOpts.isCrossTreeDrag && !treeList.length) {
3227
3489
  teOns.onDragover = $xeTree.handleCrossTreeNodeDragoverEmptyEvent;
3228
3490
  }
3229
- return h('div', Object.assign({ ref: refElem, class: ['vxe-tree', {
3491
+ return h('div', Object.assign({ ref: refElem, class: [
3492
+ 'vxe-tree',
3493
+ useScrollbar ? `ov-x--${scrollXVisible === false ? 'hidden' : 'visible'}` : '',
3494
+ useScrollbar ? `ov-y--${scrollYVisible === false ? 'hidden' : 'visible'}` : '',
3495
+ useScrollbar ? `sx-pos--${scrollbarXToTop ? 'top' : 'bottom'}` : '',
3496
+ useScrollbar ? `sy-pos--${scrollbarYToLeft ? 'left' : 'right'}` : '',
3497
+ {
3230
3498
  [`size--${vSize}`]: vSize,
3231
3499
  'show--line': showLine,
3500
+ 'is--virtual-scrollbar': useScrollbar,
3501
+ 'ov-padding': useScrollbar && scrollbarOpts.padding,
3502
+ 'ov-x--auto-hide': useScrollbar && scrollXAutoHide,
3503
+ 'ov-y--auto-hide': useScrollbar && scrollYAutoHide,
3504
+ 'overflow-y': yThumbHeight,
3505
+ 'overflow-x': xThumbWidth,
3232
3506
  'checkbox--highlight': checkboxOpts.highlight,
3233
3507
  'radio--highlight': radioOpts.highlight,
3234
3508
  'node--hover': isNodeHover,
3235
3509
  'node--trigger': trigger === 'node',
3236
3510
  'is--loading': loading
3237
- }] }, teOns), [
3511
+ }
3512
+ ], style: wrapperStyles }, teOns), [
3238
3513
  headerSlot
3239
3514
  ? h('div', {
3240
3515
  ref: refHeaderWrapperElem,
@@ -3267,6 +3542,49 @@ export default defineVxeComponent({
3267
3542
  class: 'vxe-tree--footer-wrapper'
3268
3543
  }, footerSlot({ $tree: $xeTree }))
3269
3544
  : renderEmptyElement($xeTree),
3545
+ /**
3546
+ * 滚动条
3547
+ */
3548
+ useScrollbar
3549
+ ? h('div', {
3550
+ class: scrollbarWrapperClss
3551
+ }, [
3552
+ scrollXVisible === false
3553
+ ? renderEmptyElement($xeTree)
3554
+ : h('div', {
3555
+ ref: refTrackXElem,
3556
+ class: 'vxe-scrollbar--track-x',
3557
+ onClick: clickTrackXEvent
3558
+ }, [
3559
+ h('div', {
3560
+ ref: refThumbXElem,
3561
+ class: 'vxe-scrollbar--thumb-x',
3562
+ onPointerdown: pointerdownThumbXEvent,
3563
+ onPointermove: pointermoveThumbXEvent,
3564
+ onPointerup: cleatPointerThumbEvent,
3565
+ onPointercancel: cleatPointerThumbEvent,
3566
+ onLostpointercapture: cleatPointerThumbEvent
3567
+ })
3568
+ ]),
3569
+ scrollYVisible === false
3570
+ ? renderEmptyElement($xeTree)
3571
+ : h('div', {
3572
+ ref: refTrackYElem,
3573
+ class: 'vxe-scrollbar--track-y',
3574
+ onClick: clickTrackYEvent
3575
+ }, [
3576
+ h('div', {
3577
+ ref: refThumbYElem,
3578
+ class: 'vxe-scrollbar--thumb-y',
3579
+ onPointerdown: pointerdownThumbYEvent,
3580
+ onPointermove: pointermoveThumbYEvent,
3581
+ onPointerup: cleatPointerThumbEvent,
3582
+ onPointercancel: cleatPointerThumbEvent,
3583
+ onLostpointercapture: cleatPointerThumbEvent
3584
+ })
3585
+ ])
3586
+ ])
3587
+ : renderEmptyElement($xeTree),
3270
3588
  /**
3271
3589
  * 拖拽提示
3272
3590
  */
@@ -3350,21 +3668,42 @@ export default defineVxeComponent({
3350
3668
  watch(() => props.filterValue, () => {
3351
3669
  triggerSearchEvent(new Event('filter'));
3352
3670
  });
3353
- const hFlag = ref(0);
3671
+ const reFlag = ref(0);
3354
3672
  watch(() => props.height, () => {
3355
- hFlag.value++;
3673
+ reFlag.value++;
3356
3674
  });
3357
3675
  watch(() => props.minHeight, () => {
3358
- hFlag.value++;
3676
+ reFlag.value++;
3359
3677
  });
3360
3678
  watch(() => props.maxHeight, () => {
3361
- hFlag.value++;
3679
+ reFlag.value++;
3362
3680
  });
3363
- watch(hFlag, () => {
3364
- recalculate();
3681
+ watch(() => props.useScrollbar, () => {
3682
+ reFlag.value++;
3683
+ });
3684
+ watch(computeScrollYWidth, () => {
3685
+ reFlag.value++;
3686
+ });
3687
+ watch(computeScrollXHeight, () => {
3688
+ reFlag.value++;
3689
+ });
3690
+ watch(computeScrollXVisible, () => {
3691
+ nextTick(() => {
3692
+ reFlag.value++;
3693
+ });
3694
+ });
3695
+ watch(computeScrollYVisible, () => {
3696
+ nextTick(() => {
3697
+ reFlag.value++;
3698
+ });
3699
+ });
3700
+ watch(reFlag, () => {
3701
+ recalculate().then(() => {
3702
+ recalculate();
3703
+ });
3365
3704
  });
3366
3705
  onMounted(() => {
3367
- const { transform, drag, menuConfig, showOverflow, lazy, loadMethod } = props;
3706
+ const { transform, drag, menuConfig, showOverflow, lazy, loadMethod, autoResize, useScrollbar } = props;
3368
3707
  const dragOpts = computeDragOpts.value;
3369
3708
  if (!showOverflow) {
3370
3709
  errLog('vxe.error.errProp', ['show-overflow=false', 'show-overflow=true']);
@@ -3385,12 +3724,25 @@ export default defineVxeComponent({
3385
3724
  if (menuConfig && !VxeUIContextMenu) {
3386
3725
  errLog('vxe.error.reqComp', ['vxe-context-menu']);
3387
3726
  }
3388
- if (props.autoResize) {
3389
- const el = refElem.value;
3727
+ const el = refElem.value;
3728
+ if (useScrollbar || autoResize) {
3729
+ const viewInnerEl = refVirtualBody.value;
3730
+ const scrollObserver = globalResize.create(() => {
3731
+ updateScrollbar();
3732
+ });
3733
+ if (el) {
3734
+ scrollObserver.observe(el);
3735
+ }
3736
+ if (viewInnerEl) {
3737
+ scrollObserver.observe(viewInnerEl);
3738
+ }
3739
+ internalData.scrollObserver = scrollObserver;
3740
+ }
3741
+ if (autoResize) {
3390
3742
  const parentEl = getParentElem();
3391
3743
  const resizeObserver = globalResize.create(() => {
3392
3744
  if (props.autoResize) {
3393
- recalculate();
3745
+ reFlag.value++;
3394
3746
  }
3395
3747
  });
3396
3748
  if (el) {
@@ -3401,14 +3753,19 @@ export default defineVxeComponent({
3401
3753
  }
3402
3754
  internalData.resizeObserver = resizeObserver;
3403
3755
  }
3404
- recalculate();
3405
- globalEvents.on($xeTree, 'resize', handleGlobalResizeEvent);
3756
+ reFlag.value++;
3757
+ globalEvents.on($xeTree, 'resize', () => {
3758
+ reFlag.value++;
3759
+ });
3406
3760
  });
3407
3761
  onBeforeUnmount(() => {
3408
- const { resizeObserver } = internalData;
3762
+ const { scrollObserver, resizeObserver } = internalData;
3409
3763
  if (resizeObserver) {
3410
3764
  resizeObserver.disconnect();
3411
3765
  }
3766
+ if (scrollObserver) {
3767
+ scrollObserver.disconnect();
3768
+ }
3412
3769
  globalEvents.off($xeTree, 'resize');
3413
3770
  XEUtils.assign(reactData, createReactData());
3414
3771
  XEUtils.assign(internalData, createInternalData());