vxe-table 4.23.8 → 4.23.9

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 (126) hide show
  1. package/dist/all.esm.js +5715 -3783
  2. package/es/components.d.ts +1 -0
  3. package/es/components.js +2 -7
  4. package/es/grid/src/emits.js +1 -15
  5. package/es/grid/src/grid.js +397 -120
  6. package/es/index.esm.js +1 -0
  7. package/es/index.js +1 -0
  8. package/es/table/module/custom/hook.js +49 -42
  9. package/es/table/module/custom/panel.js +777 -527
  10. package/es/table/module/edit/hook.js +140 -62
  11. package/es/table/module/export/export-panel.js +399 -316
  12. package/es/table/module/export/hook.js +395 -337
  13. package/es/table/module/export/import-panel.js +152 -123
  14. package/es/table/module/filter/hook.js +16 -2
  15. package/es/table/module/filter/panel.js +146 -84
  16. package/es/table/module/keyboard/hook.js +8 -4
  17. package/es/table/module/menu/panel.js +197 -126
  18. package/es/table/render/index.js +151 -98
  19. package/es/table/src/body.js +355 -233
  20. package/es/table/src/cell.js +426 -269
  21. package/es/table/src/columnInfo.js +1 -0
  22. package/es/table/src/footer.js +144 -99
  23. package/es/table/src/group.js +7 -3
  24. package/es/table/src/header.js +229 -172
  25. package/es/table/src/table.js +1503 -1030
  26. package/es/table/src/util.js +15 -19
  27. package/es/toolbar/src/toolbar.js +132 -75
  28. package/es/ui/index.js +1 -1
  29. package/es/ui/src/dom.js +9 -6
  30. package/es/ui/src/log.js +1 -1
  31. package/es/ui/src/utils.d.ts +1 -1
  32. package/lib/components.js +2 -7
  33. package/lib/grid/src/emits.js +1 -15
  34. package/lib/grid/src/grid.js +397 -120
  35. package/lib/index.common.js +1 -0
  36. package/lib/index.js +1 -0
  37. package/lib/index.umd.js +5732 -3800
  38. package/lib/index.umd.min.js +3 -3
  39. package/lib/table/module/custom/hook.js +49 -42
  40. package/lib/table/module/custom/panel.js +777 -527
  41. package/lib/table/module/edit/hook.js +140 -62
  42. package/lib/table/module/export/export-panel.js +399 -316
  43. package/lib/table/module/export/hook.js +395 -337
  44. package/lib/table/module/export/import-panel.js +152 -123
  45. package/lib/table/module/filter/hook.js +16 -2
  46. package/lib/table/module/filter/panel.js +146 -84
  47. package/lib/table/module/keyboard/hook.js +8 -4
  48. package/lib/table/module/menu/panel.js +197 -126
  49. package/lib/table/render/index.js +151 -98
  50. package/lib/table/src/body.js +355 -233
  51. package/lib/table/src/cell.js +426 -269
  52. package/lib/table/src/columnInfo.js +1 -0
  53. package/lib/table/src/footer.js +144 -99
  54. package/lib/table/src/group.js +7 -3
  55. package/lib/table/src/header.js +229 -172
  56. package/lib/table/src/table.js +1471 -1029
  57. package/lib/table/src/util.js +15 -19
  58. package/lib/toolbar/src/toolbar.js +132 -75
  59. package/lib/ui/index.js +1 -1
  60. package/lib/ui/src/dom.js +9 -6
  61. package/lib/ui/src/log.js +1 -1
  62. package/package.json +2 -2
  63. package/packages/colgroup/index.ts +22 -22
  64. package/packages/column/index.ts +22 -22
  65. package/packages/components.ts +41 -44
  66. package/packages/grid/index.ts +18 -18
  67. package/packages/grid/src/emits.ts +5 -19
  68. package/packages/grid/src/grid.ts +2229 -1925
  69. package/packages/grid/src/props.ts +22 -23
  70. package/packages/index.ts +11 -11
  71. package/packages/locale/lang/fr-FR.ts +15 -15
  72. package/packages/locale/lang/it-IT.ts +4 -4
  73. package/packages/locale/lang/uk-UA.ts +1 -1
  74. package/packages/locale/lang/uz-UZ.ts +13 -13
  75. package/packages/locale/lang/zh-CN.ts +907 -907
  76. package/packages/table/index.ts +26 -26
  77. package/packages/table/module/custom/hook.ts +510 -503
  78. package/packages/table/module/custom/panel.ts +2002 -1743
  79. package/packages/table/module/edit/hook.ts +1224 -1131
  80. package/packages/table/module/export/export-panel.ts +697 -611
  81. package/packages/table/module/export/hook.ts +2160 -2059
  82. package/packages/table/module/export/import-panel.ts +319 -279
  83. package/packages/table/module/export/util.ts +25 -24
  84. package/packages/table/module/filter/hook.ts +519 -501
  85. package/packages/table/module/filter/panel.ts +368 -304
  86. package/packages/table/module/keyboard/hook.ts +498 -494
  87. package/packages/table/module/menu/hook.ts +330 -330
  88. package/packages/table/module/menu/panel.ts +272 -201
  89. package/packages/table/module/validator/hook.ts +653 -635
  90. package/packages/table/render/index.ts +1819 -1744
  91. package/packages/table/src/body.ts +1078 -955
  92. package/packages/table/src/cell.ts +1524 -1359
  93. package/packages/table/src/column.ts +192 -192
  94. package/packages/table/src/columnInfo.ts +232 -232
  95. package/packages/table/src/emits.ts +134 -134
  96. package/packages/table/src/footer.ts +425 -380
  97. package/packages/table/src/group.ts +67 -63
  98. package/packages/table/src/header.ts +642 -581
  99. package/packages/table/src/props.ts +336 -336
  100. package/packages/table/src/store.ts +14 -14
  101. package/packages/table/src/table.ts +16011 -15454
  102. package/packages/table/src/use/cell-view.ts +41 -44
  103. package/packages/table/src/use/index.ts +1 -1
  104. package/packages/table/src/util.ts +1206 -1216
  105. package/packages/toolbar/index.ts +18 -18
  106. package/packages/toolbar/src/toolbar.ts +768 -706
  107. package/packages/ui/index.ts +519 -520
  108. package/packages/ui/src/anime.ts +51 -52
  109. package/packages/ui/src/comp.ts +3 -3
  110. package/packages/ui/src/dom.ts +466 -463
  111. package/packages/ui/src/log.ts +19 -19
  112. package/packages/ui/src/utils.ts +66 -66
  113. package/packages/ui/src/vn.ts +55 -55
  114. package/packages/v-x-e-table/index.d.ts +3 -3
  115. package/packages/v-x-e-table/index.ts +3 -3
  116. package/types/all.d.ts +76 -76
  117. package/types/index.d.ts +4 -4
  118. /package/dist/{iconfont.1793007753347.ttf → iconfont.1793009263429.ttf} +0 -0
  119. /package/dist/{iconfont.1793007753347.woff → iconfont.1793009263429.woff} +0 -0
  120. /package/dist/{iconfont.1793007753347.woff2 → iconfont.1793009263429.woff2} +0 -0
  121. /package/es/{iconfont.1793007753347.ttf → iconfont.1793009263429.ttf} +0 -0
  122. /package/es/{iconfont.1793007753347.woff → iconfont.1793009263429.woff} +0 -0
  123. /package/es/{iconfont.1793007753347.woff2 → iconfont.1793009263429.woff2} +0 -0
  124. /package/lib/{iconfont.1793007753347.ttf → iconfont.1793009263429.ttf} +0 -0
  125. /package/lib/{iconfont.1793007753347.woff → iconfont.1793009263429.woff} +0 -0
  126. /package/lib/{iconfont.1793007753347.woff2 → iconfont.1793009263429.woff2} +0 -0
@@ -1,1216 +1,1206 @@
1
- import { watch, reactive } from 'vue'
2
- import XEUtils from 'xe-utils'
3
- import { ColumnInfo } from './columnInfo'
4
- import { isPx, isScale, queryElement } from '../../ui/src/dom'
5
- import { eqEmptyValue, hasEnableConf } from '../../ui/src/utils'
6
-
7
- import type { VxeTableConstructor, VxeTablePrivateMethods, VxeTableDefines, VxeTablePropTypes, TableReactData, TableInternalData } from '../../../types'
8
-
9
- export function createInternalData (): TableInternalData {
10
- return {
11
- tZindex: 0,
12
- currKeyField: '',
13
- isCurrDeepKey: false,
14
- elemStore: {},
15
- // 存放横向 X 虚拟滚动相关的信息
16
- scrollXStore: {
17
- preloadSize: 0,
18
- offsetSize: 0,
19
- visibleSize: 0,
20
- visibleStartIndex: 0,
21
- visibleEndIndex: 0,
22
- startIndex: 0,
23
- endIndex: 0
24
- },
25
- // 存放纵向 Y 虚拟滚动相关信息
26
- scrollYStore: {
27
- preloadSize: 0,
28
- offsetSize: 0,
29
- visibleSize: 0,
30
- visibleStartIndex: 0,
31
- visibleEndIndex: 0,
32
- startIndex: 0,
33
- endIndex: 0
34
- },
35
- // 表格宽度
36
- tableWidth: 0,
37
- // 表格高度
38
- tableHeight: 0,
39
- customHeight: 0,
40
- customMinHeight: 0,
41
- customMaxHeight: 0,
42
-
43
- // 当前 hover 行
44
- hoverRow: null,
45
- hoverCol: null,
46
- // 当前行
47
- currentRow: null,
48
- currentCol: null,
49
-
50
- // resizeObserver: undefined,
51
-
52
- // 滚动条
53
- // scrollObserver: undefined,
54
- // isThumbDrag: false,
55
- thumbDragOffset: 0,
56
- yThumbTop: 0,
57
- xThumbLeft: 0,
58
- lastScrollTop: 0,
59
- lastScrollLeft: 0,
60
-
61
- // 单选框属性,已选中保留的行
62
- radioReserveRow: null,
63
- // 复选框属性,已选中保留的行集合
64
- checkboxReserveRowMap: {},
65
- // 行数据,已展开保留的行集合
66
- rowExpandedReserveRowMap: {},
67
- // 树结构数据,已展开保留的行集合
68
- treeExpandedReserveRowMap: {},
69
- // 树结构数据,不确定状态的集合
70
- treeIndeterminateRowMaps: {},
71
- // 列表完整数据、条件处理后
72
- tableFullData: [],
73
- afterFullData: [],
74
- afterTreeFullData: [],
75
- afterGroupFullData: [],
76
- // 列表条件处理后数据集合
77
- afterFullRowMaps: {},
78
- // 树结构完整数据、条件处理后
79
- tableFullTreeData: [],
80
- // 行分组全量数据、条件处理后
81
- tableFullGroupData: [],
82
- tableSynchData: [],
83
- tableSourceData: [],
84
- // 收集的列配置(带分组)
85
- collectColumn: [],
86
- // 完整所有列(不带分组)
87
- tableFullColumn: [],
88
- // 渲染所有列
89
- visibleColumn: [],
90
-
91
- // 全量数据集(包括当前和已删除)
92
- fullAllDataRowIdData: {},
93
- // 数据集(仅当前)
94
- fullDataRowIdData: {},
95
- // 数据集(仅可视)
96
- visibleDataRowIdData: {},
97
-
98
- keepUpdateFieldMaps: {},
99
-
100
- headerFullDataColData: {},
101
- footerFullDataRowData: {},
102
-
103
- // 渲染中缓存数据
104
- sourceDataRowIdData: {},
105
- fullColumnIdData: {},
106
- fullColumnFieldData: {},
107
- fullCellHeightMaps: {},
108
-
109
- fullCellStoreMaps: {},
110
-
111
- // 合并表头单元格的数据
112
- mergeHeaderList: [],
113
- mergeHeaderMaps: {},
114
- // 已合并单元格数据集合
115
- mergeHeaderCellMaps: {},
116
- mergeHeaderRowMaps: {},
117
- mergeHeaderColMaps: {},
118
- // 合并单元格的数据
119
- mergeBodyList: [],
120
- mergeBodyMaps: {},
121
- // 已合并单元格数据集合
122
- mergeBodyCellMaps: {},
123
- mergeBodyRowMaps: {},
124
- mergeBodyColMaps: {},
125
- // 合并表尾的数据
126
- mergeFooterList: [],
127
- mergeFooterMaps: {},
128
- // 已合并表尾数据集合
129
- mergeFooterCellMaps: {},
130
- mergeFooterRowMaps: {},
131
- mergeFooterColMaps: {},
132
-
133
- // 已展开的行集合
134
- rowExpandedMaps: {},
135
- // 懒加载中的展开行的集合
136
- rowExpandLazyLoadedMaps: {},
137
- // 已展开的分组行
138
- rowGroupExpandedMaps: {},
139
- // 已展开树节点集合
140
- treeExpandedMaps: {},
141
- // 懒加载中的树节点的集合
142
- treeExpandLazyLoadedMaps: {},
143
- // 复选框属性,已选中的行集合
144
- selectCheckboxMaps: {},
145
- // 已标记的对象集
146
- pendingRowMaps: {},
147
- // 已新增的临时行
148
- insertRowMaps: {},
149
- // 已删除行
150
- removeRowMaps: {},
151
-
152
- cvCacheMaps: {},
153
-
154
- // 表头高度
155
- tHeaderHeight: 0,
156
- // 表体高度
157
- tBodyHeight: 0,
158
- // 表尾高度
159
- tFooterHeight: 0,
160
-
161
- stackHistoryStore: {
162
- undoStacks: [],
163
- redoStacks: []
164
- },
165
-
166
- teleportToWrapperElem: null,
167
- popupToWrapperElem: null,
168
- customPopupToElem: null,
169
-
170
- lastSTime: 0,
171
-
172
- // isCustomDragStatus: false,
173
-
174
- inited: false,
175
- tooltipTimeout: null,
176
- initStatus: false,
177
- isActivated: false,
178
-
179
- // keyCtxTimeout: undefined,
180
-
181
- // 刷新布局
182
- // rceTimeout: undefined,
183
- // rceRunTime: undefined,
184
- rceDelay: 0
185
-
186
- // rsePending: false,
187
-
188
- // 滚动属性
189
- // intoRunScroll: false,
190
- // inVirtualScroll: false,
191
- // inWheelScroll: false,
192
-
193
- // inHeaderScroll: false,
194
- // inBodyScroll: false,
195
- // inFooterScroll: false,
196
- // scrollRenderType?: '',
197
-
198
- // isSyncGanttScrollTop: false,
199
-
200
- // 同步滚动
201
- // lcsTimeout: undefined,
202
- // lcsRunTime: undefined,
203
-
204
- // 横向虚拟
205
- // lxRunTime: undefined,
206
- // lxTimeout: undefined,
207
- // 纵向虚拟
208
- // lyRunTime: undefined,
209
- // lyTimeout: undefined,
210
-
211
- // 动态高度
212
- // chRunTime: undefined,
213
- // chTimeout: undefined,
214
-
215
- // isResizeCellHeight: false,
216
-
217
- // _sToTime: null
218
- }
219
- }
220
-
221
- export function createReactData (): TableReactData {
222
- return {
223
- updateColFlag: 0,
224
- // 低性能的静态列
225
- staticColumns: [],
226
- // 渲染的列分组
227
- tableGroupColumn: [],
228
- // 可视区渲染的列
229
- tableColumn: [],
230
- // 渲染中的数据
231
- tableData: [],
232
- // 是否启用了横向 X 可视渲染方式加载
233
- scrollXLoad: false,
234
- // 是否启用了纵向 Y 可视渲染方式加载
235
- scrollYLoad: false,
236
- // 是否存在纵向滚动条
237
- overflowY: true,
238
- // 是否存在横向滚动条
239
- overflowX: false,
240
- // 纵向滚动条的宽度
241
- scrollbarWidth: 0,
242
- // 横向滚动条的高度
243
- scrollbarHeight: 0,
244
-
245
- // 滚动条
246
- yThumbHeight: 0,
247
- xThumbWidth: 0,
248
-
249
- // 行高
250
- rowHeight: 0,
251
- // 表格父容器的高度
252
- parentHeight: 0,
253
- // 是否使用分组表头
254
- isGroup: false,
255
- isAllOverflow: false,
256
- // 复选框属性,是否全选
257
- isAllSelected: false,
258
- // 复选框属性,有选中且非全选状态
259
- isIndeterminate: false,
260
- // 单选框属性,选中行
261
- selectRadioRow: null,
262
- // 表尾合计数据
263
- footerTableData: [],
264
- // 行分组列信息
265
- rowGroupColumn: null,
266
- // 展开列信息
267
- expandColumn: null,
268
- checkboxColumn: null,
269
- radioColumn: null,
270
- // 树节点列信息
271
- treeNodeColumn: null,
272
- hasFixedColumn: false,
273
- // 刷新列标识,当列筛选被改变时,触发表格刷新数据
274
- upDataFlag: 0,
275
- // 刷新列标识,当列的特定属性被改变时,触发表格刷新列
276
- reColumnFlag: 0,
277
- // 初始化标识
278
- initStore: {
279
- filter: false,
280
- import: false,
281
- export: false,
282
- custom: false
283
- },
284
- // 自定义列相关的信息
285
- customStore: {
286
- btnEl: null,
287
- isAll: false,
288
- isIndeterminate: false,
289
- activeBtn: false,
290
- activeWrapper: false,
291
- visible: false,
292
- maxHeight: null,
293
- defPopupStyle: {},
294
- panePopupStyle: {},
295
- oldSortMaps: {},
296
- oldFixedMaps: {},
297
- oldVisibleMaps: {}
298
- },
299
- customColumnList: [],
300
- // 当前选中的筛选列
301
- filterStore: {
302
- targetEl: null,
303
- isAllSelected: false,
304
- isIndeterminate: false,
305
- style: null,
306
- column: null,
307
- visible: false
308
- },
309
- // 存放列相关的信息
310
- columnStore: {
311
- leftList: [],
312
- centerList: [],
313
- rightList: [],
314
- resizeList: [],
315
- pxList: [],
316
- pxMinList: [],
317
- autoMinList: [],
318
- scaleList: [],
319
- scaleMinList: [],
320
- autoList: [],
321
- remainList: []
322
- },
323
- // 存放快捷菜单的信息
324
- ctxMenuStore: {
325
- selected: null,
326
- visible: false,
327
- showChild: false,
328
- selectChild: null,
329
- list: [],
330
- style: null
331
- },
332
- // 存放可编辑相关信息
333
- editStore: {
334
- indexs: {
335
- columns: []
336
- },
337
- titles: {
338
- columns: []
339
- },
340
- // 选中源
341
- selected: {
342
- row: null,
343
- column: null
344
- },
345
- // 已复制源
346
- copyed: {
347
- cut: false,
348
- rows: [],
349
- columns: []
350
- },
351
- // 激活
352
- actived: {
353
- row: null,
354
- column: null
355
- },
356
- // 当前被强制聚焦单元格,只会在鼠标点击后算聚焦
357
- focused: {
358
- row: null,
359
- column: null
360
- }
361
- },
362
- // 存放 tooltip 相关信息
363
- tooltipStore: {
364
- row: null,
365
- column: null,
366
- content: '',
367
- visible: false,
368
- type: null,
369
- currOpts: {}
370
- },
371
- // 存放数据校验相关信息
372
- validStore: {
373
- visible: false
374
- },
375
- validErrorMaps: {},
376
- // 导入相关信息
377
- importStore: {
378
- inited: false,
379
- file: null,
380
- type: '',
381
- modeList: [],
382
- typeList: [],
383
- filename: '',
384
- visible: false
385
- },
386
- importParams: {
387
- mode: '',
388
- types: null,
389
- message: true
390
- },
391
- // 导出相关信息
392
- exportStore: {
393
- inited: false,
394
- name: '',
395
- modeList: [],
396
- typeList: [],
397
- columns: [],
398
- isPrint: false,
399
- hasFooter: false,
400
- hasMerge: false,
401
- hasTree: false,
402
- hasRowGroup: false,
403
- hasColgroup: false,
404
- visible: false
405
- },
406
- exportParams: {
407
- filename: '',
408
- sheetName: '',
409
- mode: '',
410
- type: '',
411
- isColgroup: false,
412
- isMerge: false,
413
- isTreeAllExpanded: false,
414
- isRowGroupAllExpanded: false,
415
- useStyle: false,
416
- original: false,
417
- message: true,
418
- isHeader: false,
419
- isTitle: false,
420
- isFooter: false
421
- },
422
-
423
- visiblwRowsFlag: 1,
424
-
425
- isRowGroupStatus: false,
426
- rowGroupList: [],
427
- aggHandleFields: [],
428
- aggHandleAggColumns: [],
429
-
430
- rowGroupExpandedFlag: 1,
431
- rowExpandedFlag: 1,
432
- treeExpandedFlag: 1,
433
- updateCheckboxFlag: 1,
434
- pendingRowFlag: 1,
435
- insertRowFlag: 1,
436
- removeRowFlag: 1,
437
-
438
- mergeHeadFlag: 1,
439
- mergeBodyFlag: 1,
440
- mergeFootFlag: 1,
441
-
442
- rowHeightStore: {
443
- xlarge: 54,
444
- large: 52,
445
- default: 48,
446
- medium: 44,
447
- small: 40,
448
- mini: 36
449
- },
450
-
451
- scrollVMLoading: false,
452
- scrollYHeight: 0,
453
- scrollYTop: 0,
454
- isScrollYBig: false,
455
- scrollXLeft: 0,
456
- scrollXWidth: 0,
457
- isScrollXBig: false,
458
-
459
- lazScrollLoading: false,
460
-
461
- rowExpandHeightFlag: 1,
462
- calcCellHeightFlag: 1,
463
- resizeHeightFlag: 1,
464
- resizeWidthFlag: 1,
465
-
466
- isCustomStatus: false,
467
- isCustomDragStatus: true,
468
- ctPopupFlag: 1,
469
-
470
- isCrossDragRow: false,
471
- dragRow: null,
472
- isCrossDragCol: false,
473
- dragCol: null,
474
- dragTipText: '',
475
-
476
- isDragResize: false,
477
- isRowLoading: false,
478
- isColLoading: false,
479
-
480
- currColFlag: 1
481
- }
482
- }
483
-
484
- const maxKey = '__max'
485
-
486
- export function getRowMaxHeight (chRest: Record<string, number>, isForce: boolean) {
487
- if (isForce || !chRest[maxKey]) {
488
- let max = 0
489
- for (const key in chRest) {
490
- const val = chRest[key]
491
- if (key !== maxKey && XEUtils.isNumber(val) && val > max) {
492
- max = val
493
- }
494
- }
495
- chRest[maxKey] = max
496
- return max
497
- }
498
- return chRest[maxKey]
499
- }
500
-
501
- const getAllConvertColumns = (columns: any, parentColumn?: any) => {
502
- const result: any[] = []
503
- columns.forEach((column: any) => {
504
- column.parentId = parentColumn ? parentColumn.id : null
505
- if (column.visible) {
506
- if (column.children && column.children.length && column.children.some((column: any) => column.visible)) {
507
- result.push(column)
508
- result.push(...getAllConvertColumns(column.children, column))
509
- } else {
510
- result.push(column)
511
- }
512
- }
513
- })
514
- return result
515
- }
516
-
517
- export const convertHeaderColumnToRows = (originColumns: any): any[][] => {
518
- let maxLevel = 1
519
- const traverse = (column: any, parent?: any) => {
520
- if (parent) {
521
- column.level = parent.level + 1
522
- if (maxLevel < column.level) {
523
- maxLevel = column.level
524
- }
525
- }
526
- if (column.children && column.children.length && column.children.some((column: any) => column.visible)) {
527
- let colSpan = 0
528
- column.children.forEach((subColumn: any) => {
529
- if (subColumn.visible) {
530
- traverse(subColumn, column)
531
- colSpan += subColumn.colSpan
532
- }
533
- })
534
- column.colSpan = colSpan
535
- } else {
536
- column.colSpan = 1
537
- }
538
- }
539
-
540
- originColumns.forEach((column: any) => {
541
- column.level = 1
542
- traverse(column)
543
- })
544
-
545
- const rows: any[] = []
546
- for (let i = 0; i < maxLevel; i++) {
547
- rows.push([])
548
- }
549
-
550
- const allColumns = getAllConvertColumns(originColumns)
551
-
552
- allColumns.forEach((column) => {
553
- if (column.children && column.children.length && column.children.some((column: any) => column.visible)) {
554
- column.rowSpan = 1
555
- } else {
556
- column.rowSpan = maxLevel - column.level + 1
557
- }
558
- rows[column.level - 1].push(column)
559
- })
560
-
561
- return rows
562
- }
563
-
564
- export function convertHeaderToGridRows (spanColumns: VxeTableDefines.ColumnInfo[][]) {
565
- const rSize = spanColumns.length
566
- const cSize = spanColumns[0].reduce((sum, cell) => sum + cell.colSpan, 0)
567
-
568
- const occupiedRows: boolean[][] = []
569
- const fullRows: any[][] = []
570
- for (let rIndex = 0; rIndex < rSize; rIndex++) {
571
- const oCols: boolean[] = []
572
- const dCols: string[] = []
573
- for (let cIndex = 0; cIndex < cSize; cIndex++) {
574
- oCols.push(false)
575
- dCols.push('')
576
- }
577
- occupiedRows.push(oCols)
578
- fullRows.push(dCols)
579
- }
580
-
581
- for (let rIndex = 0; rIndex < rSize; rIndex++) {
582
- let currColIndex = 0
583
- for (const column of spanColumns[rIndex]) {
584
- const { colSpan, rowSpan } = column
585
- let startColIndex = -1
586
- for (let ccIndex = currColIndex; ccIndex <= cSize - colSpan; ccIndex++) {
587
- let oFlag = true
588
- for (let csIndex = 0; csIndex < colSpan; csIndex++) {
589
- if (occupiedRows[rIndex][ccIndex + csIndex]) {
590
- oFlag = false
591
- break
592
- }
593
- }
594
- if (oFlag) {
595
- startColIndex = ccIndex
596
- break
597
- }
598
- }
599
- if (startColIndex === -1) {
600
- for (let j = 0; j <= cSize - colSpan; j++) {
601
- let oFlag = true
602
- for (let k = 0; k < colSpan; k++) {
603
- if (occupiedRows[rIndex][j + k]) {
604
- oFlag = false
605
- break
606
- }
607
- }
608
- if (oFlag) {
609
- startColIndex = j
610
- break
611
- }
612
- }
613
- if (startColIndex === -1) {
614
- // error
615
- break
616
- }
617
- }
618
-
619
- for (let srIndex = rIndex; srIndex < rIndex + rowSpan; srIndex++) {
620
- for (let scIndex = startColIndex; scIndex < startColIndex + colSpan; scIndex++) {
621
- occupiedRows[srIndex][scIndex] = true
622
- fullRows[srIndex][scIndex] = column
623
- }
624
- }
625
- currColIndex = startColIndex + colSpan
626
- }
627
- }
628
- return fullRows
629
- }
630
-
631
- export function restoreScrollLocation ($xeTable: VxeTableConstructor, scrollLeft: number, scrollTop: number) {
632
- const internalData = $xeTable.internalData
633
-
634
- if (scrollLeft || scrollTop) {
635
- internalData.intoRunScroll = false
636
- internalData.inVirtualScroll = false
637
- internalData.inWheelScroll = false
638
- internalData.inHeaderScroll = false
639
- internalData.inBodyScroll = false
640
- internalData.inFooterScroll = false
641
- internalData.scrollRenderType = ''
642
- // 还原滚动状态
643
- return $xeTable.scrollTo(scrollLeft, scrollTop)
644
- }
645
- return $xeTable.clearScroll()
646
- }
647
-
648
- export function getRowUniqueId () {
649
- return XEUtils.uniqueId('row_')
650
- }
651
-
652
- /**
653
- * 生成行的唯一主键
654
- */
655
- export function createRowId (rowOpts: VxeTablePropTypes.RowConfig, row: any, keyField: string) {
656
- const { createKeyMethod } = rowOpts
657
- if (createKeyMethod) {
658
- return createKeyMethod({ row, keyField })
659
- }
660
- return getRowUniqueId()
661
- }
662
-
663
- export function hasDeepKey (rowKey: string) {
664
- return rowKey.indexOf('.') > -1
665
- }
666
-
667
- // 行主键 key
668
- export function getRowkey ($xeTable: VxeTableConstructor) {
669
- const { currKeyField } = $xeTable.internalData
670
- return currKeyField
671
- }
672
-
673
- // 行主键 value
674
- export function getRowid ($xeTable: VxeTableConstructor, row: any) {
675
- const internalData = $xeTable.internalData
676
- const { isCurrDeepKey, currKeyField } = internalData
677
- return row ? encodeRowid((isCurrDeepKey ? getDeepRowIdByKey : getFastRowIdByKey)(row, currKeyField)) : ''
678
- }
679
-
680
- export function createHandleUpdateRowId ($xeTable: VxeTableConstructor) {
681
- const internalData = $xeTable.internalData
682
- const { isCurrDeepKey, currKeyField } = internalData
683
- const { computeRowOpts } = $xeTable.getComputeMaps()
684
- const rowOpts = computeRowOpts.value
685
- const updateRId = isCurrDeepKey ? updateDeepRowKey : updateFastRowKey
686
- return {
687
- rowKey: currKeyField,
688
- handleUpdateRowId (row: any) {
689
- return row ? updateRId(rowOpts, row, currKeyField) : ''
690
- }
691
- }
692
- }
693
-
694
- export function createHandleGetRowId ($xeTable: VxeTableConstructor) {
695
- const internalData = $xeTable.internalData
696
- const { isCurrDeepKey, currKeyField } = internalData
697
- const getRId = isCurrDeepKey ? getDeepRowIdByKey : getFastRowIdByKey
698
- return {
699
- rowKey: currKeyField,
700
- handleGetRowId (row: any) {
701
- return row ? encodeRowid(getRId(row, currKeyField)) : ''
702
- }
703
- }
704
- }
705
-
706
- // 编码行主键
707
- export function encodeRowid (rowVal: string | number) {
708
- return XEUtils.eqNull(rowVal) ? '' : encodeURIComponent(rowVal)
709
- }
710
-
711
- function getDeepRowIdByKey (row: any, rowKey: string | number) {
712
- return XEUtils.get(row, rowKey)
713
- }
714
-
715
- function updateDeepRowKey (rowOpts: VxeTablePropTypes.RowConfig, row: any, rowKey: string) {
716
- let rowid = encodeRowid(getDeepRowIdByKey(row, rowKey))
717
- if (eqEmptyValue(rowid)) {
718
- const newRowid = createRowId(rowOpts, row, rowKey)
719
- rowid = '' + newRowid
720
- XEUtils.set(row, rowKey, rowid)
721
- }
722
- return rowid
723
- }
724
-
725
- function getFastRowIdByKey (row: any, rowKey: string) {
726
- return row[rowKey]
727
- }
728
-
729
- function updateFastRowKey (rowOpts: VxeTablePropTypes.RowConfig, row: any, rowKey: string) {
730
- let rowid = encodeRowid(getFastRowIdByKey(row, rowKey))
731
- if (eqEmptyValue(rowid)) {
732
- const newRowid = createRowId(rowOpts, row, rowKey)
733
- rowid = '' + newRowid
734
- row[rowKey] = newRowid
735
- }
736
- return rowid
737
- }
738
-
739
- export interface XEColumnInstance {
740
- columnConfig: ColumnInfo;
741
- }
742
-
743
- export function handleFieldOrColumn ($xeTable: VxeTableConstructor, fieldOrColumn: string | VxeTableDefines.ColumnInfo | null) {
744
- if (fieldOrColumn) {
745
- return XEUtils.isString(fieldOrColumn) || XEUtils.isNumber(fieldOrColumn) ? $xeTable.getColumnByField(`${fieldOrColumn}`) : fieldOrColumn
746
- }
747
- return null
748
- }
749
-
750
- export function handleRowidOrRow ($xeTable: VxeTableConstructor, rowidOrRow: any) {
751
- if (rowidOrRow) {
752
- const rowid = XEUtils.isString(rowidOrRow) || XEUtils.isNumber(rowidOrRow) ? rowidOrRow : getRowid($xeTable, rowidOrRow)
753
- return $xeTable.getRowById(rowid)
754
- }
755
- return null
756
- }
757
-
758
- export function getCellRestHeight (rowRest: VxeTableDefines.RowCacheItem, cellOpts: VxeTablePropTypes.CellConfig, rowOpts: VxeTablePropTypes.RowConfig, defaultRowHeight: number) {
759
- const { height, minHeight, maxHeight } = cellOpts
760
- let cellHeight = rowRest.resizeHeight || height || rowOpts.height || rowRest.height || defaultRowHeight
761
- if (maxHeight && maxHeight <= cellHeight) {
762
- cellHeight = maxHeight
763
- }
764
- if (minHeight && minHeight >= cellHeight) {
765
- cellHeight = minHeight
766
- }
767
- return cellHeight
768
- }
769
-
770
- function getPaddingLeftRightSize (elem: HTMLElement | null) {
771
- if (elem) {
772
- const computedStyle = getComputedStyle(elem)
773
- const paddingLeft = XEUtils.toNumber(computedStyle.paddingLeft)
774
- const paddingRight = XEUtils.toNumber(computedStyle.paddingRight)
775
- return paddingLeft + paddingRight
776
- }
777
- return 0
778
- }
779
-
780
- function getElementMarginAndWidth (elem: HTMLElement | null) {
781
- if (elem) {
782
- const computedStyle = getComputedStyle(elem)
783
- const marginLeft = XEUtils.toNumber(computedStyle.marginLeft)
784
- const marginRight = XEUtils.toNumber(computedStyle.marginRight)
785
- return elem.offsetWidth + marginLeft + marginRight
786
- }
787
- return 0
788
- }
789
-
790
- export function toFilters (filters: any, colid?: string | number) {
791
- if (filters) {
792
- if (XEUtils.isArray(filters)) {
793
- return filters.map(({ label, value, data, resetValue, checked }) => {
794
- return { label, value, data, resetValue, checked: !!checked, _checked: !!checked, _colId: colid }
795
- })
796
- }
797
- return []
798
- }
799
- return filters
800
- }
801
-
802
- export function toTreePathSeq (path: any[]) {
803
- return path.map((num, i) => i % 2 === 0 ? (Number(num) + 1) : '.').join('')
804
- }
805
-
806
- export function getCellValue (row: any, column: VxeTableDefines.ColumnInfo | null) {
807
- if (column) {
808
- return XEUtils.get(row, column.field)
809
- }
810
- return null
811
- }
812
-
813
- export function setCellValue (row: any, column: VxeTableDefines.ColumnInfo | null, value: any) {
814
- if (column) {
815
- XEUtils.set(row, column.field, value)
816
- }
817
- }
818
-
819
- export function getRefElem (refEl: any) {
820
- if (refEl) {
821
- const rest = refEl.value
822
- if (rest) {
823
- return (rest.$el || rest) as HTMLElement
824
- }
825
- }
826
- return null
827
- }
828
-
829
- export function getCalcHeight (height: number | 'unset' | undefined | null) {
830
- if (height === 'unset') {
831
- return 0
832
- }
833
- return height || 0
834
- }
835
-
836
- /**
837
- * 列宽拖动最大宽度
838
- */
839
- export function getColReMaxWidth (params: (VxeTableDefines.CellRenderHeaderParams| VxeTableDefines.CellRenderBodyParams | VxeTableDefines.CellRenderFooterParams) & { cell: HTMLTableCellElement }) {
840
- const { $table, column, cell } = params
841
- const internalData = $table.internalData
842
- const { elemStore } = internalData
843
- const { computeColumnOpts, computeResizableOpts } = $table.getComputeMaps()
844
- const resizableOpts = computeResizableOpts.value
845
- const columnOpts = computeColumnOpts.value
846
- const { maxWidth: reMaxWidth } = resizableOpts
847
- const colMaxWidth = column.maxWidth || columnOpts.maxWidth
848
- // 如果自定义调整宽度逻辑
849
- if (reMaxWidth) {
850
- const customMaxWidth = XEUtils.isFunction(reMaxWidth) ? reMaxWidth(params) : reMaxWidth
851
- if (customMaxWidth !== 'auto') {
852
- return Math.max(1, XEUtils.toNumber(customMaxWidth))
853
- }
854
- }
855
- const minTitleWidth = XEUtils.floor((XEUtils.toNumber(getComputedStyle(cell).fontSize) || 14) * 1.8)
856
- const paddingLeftRight = getPaddingLeftRightSize(cell) + getPaddingLeftRightSize(queryElement(cell, '.vxe-cell'))
857
- const mWidth = minTitleWidth + paddingLeftRight
858
- // 如果设置最小宽
859
- if (colMaxWidth) {
860
- const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
861
- if (bodyScrollElem) {
862
- if (isScale(colMaxWidth)) {
863
- const bodyWidth = bodyScrollElem.clientWidth - 1
864
- const meanWidth = bodyWidth / 100
865
- return Math.max(mWidth, Math.floor(XEUtils.toInteger(colMaxWidth) * meanWidth))
866
- } else if (isPx(colMaxWidth)) {
867
- return Math.max(mWidth, XEUtils.toInteger(colMaxWidth))
868
- }
869
- }
870
- }
871
- return -1
872
- }
873
-
874
- /**
875
- * 列宽拖动最小宽度
876
- */
877
- export function getColReMinWidth (params: (VxeTableDefines.CellRenderHeaderParams| VxeTableDefines.CellRenderBodyParams | VxeTableDefines.CellRenderFooterParams) & { cell: HTMLTableCellElement }) {
878
- const { $table, column, cell } = params
879
- const tableProps = $table.props
880
- const internalData = $table.internalData
881
- const { computeColumnOpts, computeResizableOpts } = $table.getComputeMaps()
882
- const resizableOpts = computeResizableOpts.value
883
- const columnOpts = computeColumnOpts.value
884
- const { minWidth: reMinWidth } = resizableOpts
885
- // 如果自定义调整宽度逻辑
886
- if (reMinWidth) {
887
- const customMinWidth = XEUtils.isFunction(reMinWidth) ? reMinWidth(params) : reMinWidth
888
- if (customMinWidth !== 'auto') {
889
- return Math.max(1, XEUtils.toNumber(customMinWidth))
890
- }
891
- }
892
- const { elemStore } = internalData
893
- const { showHeaderOverflow: allColumnHeaderOverflow } = tableProps
894
- const { showHeaderOverflow } = column
895
- const colMinWidth = column.minWidth || columnOpts.minWidth
896
- const headOverflow = XEUtils.isUndefined(showHeaderOverflow) || XEUtils.isNull(showHeaderOverflow) ? allColumnHeaderOverflow : showHeaderOverflow
897
- const showEllipsis = headOverflow === 'ellipsis'
898
- const showTitle = headOverflow === 'title'
899
- const showTooltip = headOverflow === true || headOverflow === 'tooltip'
900
- const hasEllipsis = showTitle || showTooltip || showEllipsis
901
- const minTitleWidth = XEUtils.floor((XEUtils.toNumber(getComputedStyle(cell).fontSize) || 14) * 1.8)
902
- const paddingLeftRight = getPaddingLeftRightSize(cell) + getPaddingLeftRightSize(queryElement(cell, '.vxe-cell'))
903
- let mWidth = minTitleWidth + paddingLeftRight
904
- // 默认最小宽处理
905
- if (hasEllipsis) {
906
- const dragIconWidth = getElementMarginAndWidth(queryElement(cell, '.vxe-cell--drag-handle'))
907
- const checkboxIconWidth = getElementMarginAndWidth(queryElement(cell, '.vxe-cell--checkbox'))
908
- const requiredIconWidth = getElementMarginAndWidth(queryElement(cell, '.vxe-cell--required-icon'))
909
- const editIconWidth = getElementMarginAndWidth(queryElement(cell, '.vxe-cell--edit-icon'))
910
- const prefixIconWidth = getElementMarginAndWidth(queryElement(cell, '.vxe-cell-title-prefix-icon'))
911
- const suffixIconWidth = getElementMarginAndWidth(queryElement(cell, '.vxe-cell-title-suffix-icon'))
912
- const sortIconWidth = getElementMarginAndWidth(queryElement(cell, '.vxe-cell--sort'))
913
- const filterIconWidth = getElementMarginAndWidth(queryElement(cell, '.vxe-cell--filter'))
914
- mWidth += dragIconWidth + checkboxIconWidth + requiredIconWidth + editIconWidth + prefixIconWidth + suffixIconWidth + filterIconWidth + sortIconWidth
915
- }
916
- // 如果设置最小宽
917
- if (colMinWidth) {
918
- const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
919
- if (bodyScrollElem) {
920
- if (isScale(colMinWidth)) {
921
- const bodyWidth = bodyScrollElem.clientWidth - 1
922
- const meanWidth = bodyWidth / 100
923
- return Math.max(mWidth, Math.floor(XEUtils.toInteger(colMinWidth) * meanWidth))
924
- } else if (isPx(colMinWidth)) {
925
- return Math.max(mWidth, XEUtils.toInteger(colMinWidth))
926
- }
927
- }
928
- }
929
- return mWidth
930
- }
931
-
932
- export function isColumnInfo (column: any): column is ColumnInfo {
933
- return column && (column.constructor === ColumnInfo || column instanceof ColumnInfo)
934
- }
935
-
936
- // 获取所有的列,排除分组
937
- export function getColumnList (columns: VxeTableDefines.ColumnInfo[]) {
938
- const result: VxeTableDefines.ColumnInfo[] = []
939
- columns.forEach((column) => {
940
- result.push(...(column.children && column.children.length ? getColumnList(column.children) : [column]))
941
- })
942
- return result
943
- }
944
-
945
- export function createColumn ($xeTable: VxeTableConstructor & VxeTablePrivateMethods, options: VxeTableDefines.ColumnOptions | VxeTableDefines.ColumnInfo, renderOptions: any): any {
946
- return isColumnInfo(options) ? options : reactive(new ColumnInfo($xeTable, options, renderOptions))
947
- }
948
-
949
- export function watchColumn ($xeTable: VxeTableConstructor & VxeTablePrivateMethods, props: any, column: ColumnInfo) {
950
- Object.keys(props).forEach(name => {
951
- watch(() => props[name], (value: any) => {
952
- column.update(name, value)
953
- if ($xeTable) {
954
- if (name === 'filters') {
955
- $xeTable.setFilter(column as any, value)
956
- $xeTable.handleUpdateDataQueue()
957
- } else if (['visible', 'fixed', 'width', 'minWidth', 'maxWidth'].includes(name)) {
958
- $xeTable.handleRefreshColumnQueue()
959
- }
960
- }
961
- })
962
- })
963
- }
964
-
965
- export function assembleColumn ($xeTable: VxeTableConstructor & VxeTablePrivateMethods, elem: HTMLElement, column: ColumnInfo, colgroup: XEColumnInstance | null) {
966
- const { reactData } = $xeTable
967
- const { staticColumns } = reactData
968
- const parentElem = elem.parentNode
969
- const parentColumn = colgroup ? colgroup.columnConfig : null
970
- const parentCols = parentColumn ? parentColumn.children : staticColumns
971
- if (parentElem && parentCols) {
972
- column.defaultParentId = parentColumn ? parentColumn.id : null
973
- parentCols.splice(XEUtils.arrayIndexOf(parentElem.children, elem), 0, column)
974
- reactData.staticColumns = staticColumns.slice(0)
975
- }
976
- }
977
-
978
- export function destroyColumn ($xeTable: VxeTableConstructor & VxeTablePrivateMethods, column: ColumnInfo) {
979
- const { reactData } = $xeTable
980
- const { staticColumns } = reactData
981
- const matchObj = XEUtils.findTree(staticColumns, item => item.id === column.id, { children: 'children' })
982
- if (matchObj) {
983
- matchObj.items.splice(matchObj.index, 1)
984
- }
985
- reactData.staticColumns = staticColumns.slice(0)
986
- }
987
-
988
- export function getRootColumn ($xeTable: VxeTableConstructor & VxeTablePrivateMethods, column: ColumnInfo) {
989
- const { internalData } = $xeTable
990
-
991
- const { fullColumnIdData } = internalData
992
- if (!column) {
993
- return null
994
- }
995
- let parentColId = column.parentId
996
- while (fullColumnIdData[parentColId]) {
997
- const column = fullColumnIdData[parentColId].column
998
- parentColId = column.parentId
999
- if (!parentColId) {
1000
- return column
1001
- }
1002
- }
1003
- return column
1004
- }
1005
-
1006
- export function getFirstChildColumn (column: VxeTableDefines.ColumnInfo): VxeTableDefines.ColumnInfo {
1007
- const { children } = column
1008
- if (children && children.length) {
1009
- return getFirstChildColumn(XEUtils.first(children))
1010
- }
1011
- return column
1012
- }
1013
-
1014
- export function getLastChildColumn (column: VxeTableDefines.ColumnInfo): VxeTableDefines.ColumnInfo {
1015
- const { children } = column
1016
- if (children && children.length) {
1017
- return getFirstChildColumn(XEUtils.last(children))
1018
- }
1019
- return column
1020
- }
1021
-
1022
- export function clearTableDefaultStatus ($xeTable: VxeTableConstructor & VxeTablePrivateMethods) {
1023
- const { props, internalData } = $xeTable
1024
-
1025
- const { keyboardConfig, mouseConfig } = props
1026
- const { computeMouseOpts, computeKeyboardOpts } = $xeTable.getComputeMaps()
1027
- const mouseOpts = computeMouseOpts.value
1028
- const keyboardOpts = computeKeyboardOpts.value
1029
- internalData.initStatus = false
1030
- const actionList = [
1031
- $xeTable.clearSort(),
1032
- $xeTable.clearCurrentRow(),
1033
- $xeTable.clearCurrentColumn(),
1034
- $xeTable.clearRadioRow(),
1035
- $xeTable.clearRadioReserve(),
1036
- $xeTable.clearCheckboxRow(),
1037
- $xeTable.clearCheckboxReserve(),
1038
- $xeTable.clearRowExpand(),
1039
- $xeTable.clearTreeExpand(),
1040
- $xeTable.clearTreeExpandReserve(),
1041
- $xeTable.clearPendingRow()
1042
- ]
1043
- if ($xeTable.clearFilter) {
1044
- actionList.push(
1045
- $xeTable.clearFilter()
1046
- )
1047
- }
1048
- if ($xeTable.clearSelected && (hasEnableConf(keyboardConfig, keyboardOpts) || hasEnableConf(mouseConfig, mouseOpts))) {
1049
- actionList.push(
1050
- $xeTable.clearSelected()
1051
- )
1052
- }
1053
- if ($xeTable.clearCellAreas && hasEnableConf(mouseConfig, mouseOpts)) {
1054
- actionList.push(
1055
- $xeTable.clearCellAreas(),
1056
- $xeTable.clearCopyCellArea()
1057
- )
1058
- }
1059
- return Promise.all(actionList).then(() => {
1060
- return $xeTable.clearScroll()
1061
- })
1062
- }
1063
-
1064
- export function clearTableAllStatus ($xeTable: VxeTableConstructor & VxeTablePrivateMethods) {
1065
- if ($xeTable.clearFilter) {
1066
- $xeTable.clearFilter()
1067
- }
1068
- return clearTableDefaultStatus($xeTable)
1069
- }
1070
-
1071
- export function rowToVisible ($xeTable: VxeTableConstructor & VxeTablePrivateMethods, row: any) {
1072
- const reactData = $xeTable.reactData
1073
- const internalData = $xeTable.internalData
1074
-
1075
- const { computeLeftFixedWidth, computeRightFixedWidth, computeRowOpts, computeCellOpts, computeDefaultRowHeight } = $xeTable.getComputeMaps()
1076
- const { scrollYLoad, scrollYTop, isAllOverflow } = reactData
1077
- const { elemStore, afterFullData, fullAllDataRowIdData, isResizeCellHeight } = internalData
1078
- const rowOpts = computeRowOpts.value
1079
- const cellOpts = computeCellOpts.value
1080
- const defaultRowHeight = computeDefaultRowHeight.value
1081
- const leftFixedWidth = computeLeftFixedWidth.value
1082
- const rightFixedWidth = computeRightFixedWidth.value
1083
- const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
1084
- const rowid = getRowid($xeTable, row)
1085
- if (bodyScrollElem) {
1086
- const bodyHeight = bodyScrollElem.clientHeight
1087
- const bodyScrollTop = bodyScrollElem.scrollTop
1088
- const trElem: HTMLTableRowElement | null = bodyScrollElem.querySelector(`[rowid="${rowid}"]`)
1089
- if (trElem) {
1090
- const trOffsetTop = trElem.offsetTop + (scrollYLoad ? scrollYTop : 0)
1091
- const trHeight = trElem.clientHeight
1092
- // 检测行是否在可视区中
1093
- if (trOffsetTop < bodyScrollTop || trOffsetTop > bodyScrollTop + bodyHeight) {
1094
- return $xeTable.scrollTo(null, trOffsetTop)
1095
- } else if (trOffsetTop + trHeight >= bodyHeight + bodyScrollTop) {
1096
- return $xeTable.scrollTo(null, bodyScrollTop + trHeight)
1097
- }
1098
- } else {
1099
- // 如果是虚拟渲染滚动
1100
- if (scrollYLoad) {
1101
- const isCustomCellHeight = isResizeCellHeight || cellOpts.height || rowOpts.height
1102
- if (!isCustomCellHeight && isAllOverflow) {
1103
- return $xeTable.scrollTo(null, ($xeTable.findRowIndexOf(afterFullData, row) - 1) * defaultRowHeight)
1104
- }
1105
- const rowRest = fullAllDataRowIdData[rowid] || {}
1106
- const rHeight = rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight
1107
- const scrollTop = rowRest.oTop
1108
- if (scrollTop < bodyScrollTop) {
1109
- return $xeTable.scrollTo(null, scrollTop - leftFixedWidth - 1)
1110
- }
1111
- return $xeTable.scrollTo(null, (scrollTop + rHeight) - (bodyHeight - rightFixedWidth - 1))
1112
- }
1113
- }
1114
- }
1115
- return Promise.resolve()
1116
- }
1117
-
1118
- export function colToVisible ($xeTable: VxeTableConstructor & VxeTablePrivateMethods, isForce: boolean, column: VxeTableDefines.ColumnInfo, row?: any) {
1119
- const reactData = $xeTable.reactData
1120
- const internalData = $xeTable.internalData
1121
-
1122
- const { computeLeftFixedWidth, computeRightFixedWidth } = $xeTable.getComputeMaps()
1123
- const { scrollXLoad, scrollXLeft } = reactData
1124
- const { elemStore, visibleColumn } = internalData
1125
- const leftFixedWidth = computeLeftFixedWidth.value
1126
- const rightFixedWidth = computeRightFixedWidth.value
1127
- const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
1128
- if (column.fixed) {
1129
- return Promise.resolve()
1130
- }
1131
- if (bodyScrollElem) {
1132
- const bodyWidth = bodyScrollElem.clientWidth
1133
- const bodyScrollLeft = bodyScrollElem.scrollLeft
1134
- let tdElem: HTMLTableCellElement | null = null
1135
- if (row) {
1136
- const rowid = getRowid($xeTable, row)
1137
- tdElem = bodyScrollElem.querySelector(`[rowid="${rowid}"] .${column.id}`)
1138
- }
1139
- if (!tdElem) {
1140
- tdElem = bodyScrollElem.querySelector(`.${column.id}`)
1141
- }
1142
- if (tdElem) {
1143
- const tdOffsetLeft = tdElem.offsetLeft + (scrollXLoad ? scrollXLeft : 0)
1144
- const cellWidth = tdElem.clientWidth
1145
- // 检测是否在可视区中
1146
- if (isForce || (
1147
- !(tdOffsetLeft <= (bodyScrollLeft + leftFixedWidth) && (tdOffsetLeft + cellWidth) > (bodyScrollLeft + leftFixedWidth)) &&
1148
- !(tdOffsetLeft >= (bodyScrollLeft + leftFixedWidth) && tdOffsetLeft < (bodyScrollLeft + bodyWidth - rightFixedWidth))
1149
- )) {
1150
- if (tdOffsetLeft < (bodyScrollLeft + leftFixedWidth)) {
1151
- return $xeTable.scrollTo(tdOffsetLeft - leftFixedWidth - 1)
1152
- } else if ((tdOffsetLeft + cellWidth - bodyScrollLeft) > (bodyWidth - rightFixedWidth)) {
1153
- return $xeTable.scrollTo((tdOffsetLeft + cellWidth) - (bodyWidth - rightFixedWidth - 1))
1154
- }
1155
- }
1156
- } else {
1157
- if (scrollXLoad) {
1158
- let tdOffsetLeft = 0
1159
- const cellWidth = column.renderWidth
1160
- for (let i = 0; i < visibleColumn.length; i++) {
1161
- const currCol = visibleColumn[i]
1162
- if (currCol === column || currCol.id === column.id) {
1163
- break
1164
- }
1165
- tdOffsetLeft += currCol.renderWidth
1166
- }
1167
- // 检测是否在可视区中
1168
- if (isForce || (
1169
- !(tdOffsetLeft <= (bodyScrollLeft + leftFixedWidth) && (tdOffsetLeft + cellWidth) > (bodyScrollLeft + leftFixedWidth)) &&
1170
- !(tdOffsetLeft >= (bodyScrollLeft + leftFixedWidth) && tdOffsetLeft < (bodyScrollLeft + bodyWidth - rightFixedWidth))
1171
- )) {
1172
- if (tdOffsetLeft < bodyScrollLeft) {
1173
- return $xeTable.scrollTo(tdOffsetLeft - leftFixedWidth - 1)
1174
- }
1175
- return $xeTable.scrollTo((tdOffsetLeft + cellWidth) - (bodyWidth - rightFixedWidth - 1))
1176
- }
1177
- }
1178
- }
1179
- }
1180
- return Promise.resolve()
1181
- }
1182
-
1183
- function hangleBolleanDefaultValue (currVal: boolean | null | undefined, defVal: boolean | null | undefined) {
1184
- return XEUtils.isBoolean(currVal) ? currVal : defVal
1185
- }
1186
-
1187
- export function handleCustomStoreConfig ($xeTable: VxeTableConstructor) {
1188
- const { computeCustomOpts } = $xeTable.getComputeMaps()
1189
- const customOpts = computeCustomOpts.value
1190
- const { storage, storeOptions } = customOpts
1191
-
1192
- const isAllCustom = storage === true
1193
- const storageOpts: VxeTableDefines.VxeTableCustomStorageObj = Object.assign({}, isAllCustom ? {} : storage || {}, storeOptions)
1194
- const isCustomAlign = hangleBolleanDefaultValue(storageOpts.align, isAllCustom)
1195
- const isCustomHeaderAlign = hangleBolleanDefaultValue(storageOpts.headerAlign, isAllCustom)
1196
- const isCustomFooterAlign = hangleBolleanDefaultValue(storageOpts.footerAlign, isAllCustom)
1197
- const isCustomResizable = hangleBolleanDefaultValue(storageOpts.resizable, isAllCustom)
1198
- const isCustomVisible = hangleBolleanDefaultValue(storageOpts.visible, isAllCustom)
1199
- const isCustomFixed = hangleBolleanDefaultValue(storageOpts.fixed, isAllCustom)
1200
- const isCustomSort = hangleBolleanDefaultValue(storageOpts.sort, isAllCustom)
1201
- const isCustomAggGroup = hangleBolleanDefaultValue(storageOpts.aggGroup, isAllCustom)
1202
- const isCustomAggFunc = hangleBolleanDefaultValue(storageOpts.aggFunc, isAllCustom)
1203
- const isCustomPager = hangleBolleanDefaultValue(storageOpts.pager, isAllCustom)
1204
- return {
1205
- isCustomAlign,
1206
- isCustomHeaderAlign,
1207
- isCustomFooterAlign,
1208
- isCustomResizable,
1209
- isCustomVisible,
1210
- isCustomFixed,
1211
- isCustomSort,
1212
- isCustomAggGroup,
1213
- isCustomAggFunc,
1214
- isCustomPager
1215
- }
1216
- }
1
+ import { watch, reactive } from 'vue'
2
+ import XEUtils from 'xe-utils'
3
+ import { ColumnInfo } from './columnInfo'
4
+ import { isPx, isScale, queryElement } from '../../ui/src/dom'
5
+ import { eqEmptyValue, hasEnableConf } from '../../ui/src/utils'
6
+
7
+ import type { VxeTableConstructor, VxeTablePrivateMethods, VxeTableDefines, VxeTablePropTypes, TableReactData, TableInternalData } from '../../../types'
8
+
9
+ export function createInternalData(): TableInternalData {
10
+ return {
11
+ tZindex: 0,
12
+ currKeyField: '',
13
+ isCurrDeepKey: false,
14
+ elemStore: {},
15
+ // 存放横向 X 虚拟滚动相关的信息
16
+ scrollXStore: {
17
+ preloadSize: 0,
18
+ offsetSize: 0,
19
+ visibleSize: 0,
20
+ visibleStartIndex: 0,
21
+ visibleEndIndex: 0,
22
+ startIndex: 0,
23
+ endIndex: 0
24
+ },
25
+ // 存放纵向 Y 虚拟滚动相关信息
26
+ scrollYStore: {
27
+ preloadSize: 0,
28
+ offsetSize: 0,
29
+ visibleSize: 0,
30
+ visibleStartIndex: 0,
31
+ visibleEndIndex: 0,
32
+ startIndex: 0,
33
+ endIndex: 0
34
+ },
35
+ // 表格宽度
36
+ tableWidth: 0,
37
+ // 表格高度
38
+ tableHeight: 0,
39
+ customHeight: 0,
40
+ customMinHeight: 0,
41
+ customMaxHeight: 0,
42
+
43
+ // 当前 hover 行
44
+ hoverRow: null,
45
+ hoverCol: null,
46
+ // 当前行
47
+ currentRow: null,
48
+ currentCol: null,
49
+
50
+ // resizeObserver: undefined,
51
+
52
+ // 滚动条
53
+ // scrollObserver: undefined,
54
+ // isThumbDrag: false,
55
+ thumbDragOffset: 0,
56
+ yThumbTop: 0,
57
+ xThumbLeft: 0,
58
+ lastScrollTop: 0,
59
+ lastScrollLeft: 0,
60
+
61
+ // 单选框属性,已选中保留的行
62
+ radioReserveRow: null,
63
+ // 复选框属性,已选中保留的行集合
64
+ checkboxReserveRowMap: {},
65
+ // 行数据,已展开保留的行集合
66
+ rowExpandedReserveRowMap: {},
67
+ // 树结构数据,已展开保留的行集合
68
+ treeExpandedReserveRowMap: {},
69
+ // 树结构数据,不确定状态的集合
70
+ treeIndeterminateRowMaps: {},
71
+ // 列表完整数据、条件处理后
72
+ tableFullData: [],
73
+ afterFullData: [],
74
+ afterTreeFullData: [],
75
+ afterGroupFullData: [],
76
+ // 列表条件处理后数据集合
77
+ afterFullRowMaps: {},
78
+ // 树结构完整数据、条件处理后
79
+ tableFullTreeData: [],
80
+ // 行分组全量数据、条件处理后
81
+ tableFullGroupData: [],
82
+ tableSynchData: [],
83
+ tableSourceData: [],
84
+ // 收集的列配置(带分组)
85
+ collectColumn: [],
86
+ // 完整所有列(不带分组)
87
+ tableFullColumn: [],
88
+ // 渲染所有列
89
+ visibleColumn: [],
90
+
91
+ // 全量数据集(包括当前和已删除)
92
+ fullAllDataRowIdData: {},
93
+ // 数据集(仅当前)
94
+ fullDataRowIdData: {},
95
+ // 数据集(仅可视)
96
+ visibleDataRowIdData: {},
97
+
98
+ keepUpdateFieldMaps: {},
99
+
100
+ headerFullDataColData: {},
101
+ footerFullDataRowData: {},
102
+
103
+ // 渲染中缓存数据
104
+ sourceDataRowIdData: {},
105
+ fullColumnIdData: {},
106
+ fullColumnFieldData: {},
107
+ fullCellHeightMaps: {},
108
+
109
+ fullCellStoreMaps: {},
110
+
111
+ // 合并表头单元格的数据
112
+ mergeHeaderList: [],
113
+ mergeHeaderMaps: {},
114
+ // 已合并单元格数据集合
115
+ mergeHeaderCellMaps: {},
116
+ mergeHeaderRowMaps: {},
117
+ mergeHeaderColMaps: {},
118
+ // 合并单元格的数据
119
+ mergeBodyList: [],
120
+ mergeBodyMaps: {},
121
+ // 已合并单元格数据集合
122
+ mergeBodyCellMaps: {},
123
+ mergeBodyRowMaps: {},
124
+ mergeBodyColMaps: {},
125
+ // 合并表尾的数据
126
+ mergeFooterList: [],
127
+ mergeFooterMaps: {},
128
+ // 已合并表尾数据集合
129
+ mergeFooterCellMaps: {},
130
+ mergeFooterRowMaps: {},
131
+ mergeFooterColMaps: {},
132
+
133
+ // 已展开的行集合
134
+ rowExpandedMaps: {},
135
+ // 懒加载中的展开行的集合
136
+ rowExpandLazyLoadedMaps: {},
137
+ // 已展开的分组行
138
+ rowGroupExpandedMaps: {},
139
+ // 已展开树节点集合
140
+ treeExpandedMaps: {},
141
+ // 懒加载中的树节点的集合
142
+ treeExpandLazyLoadedMaps: {},
143
+ // 复选框属性,已选中的行集合
144
+ selectCheckboxMaps: {},
145
+ // 已标记的对象集
146
+ pendingRowMaps: {},
147
+ // 已新增的临时行
148
+ insertRowMaps: {},
149
+ // 已删除行
150
+ removeRowMaps: {},
151
+
152
+ cvCacheMaps: {},
153
+
154
+ // 表头高度
155
+ tHeaderHeight: 0,
156
+ // 表体高度
157
+ tBodyHeight: 0,
158
+ // 表尾高度
159
+ tFooterHeight: 0,
160
+
161
+ stackHistoryStore: {
162
+ undoStacks: [],
163
+ redoStacks: []
164
+ },
165
+
166
+ teleportToWrapperElem: null,
167
+ popupToWrapperElem: null,
168
+ customPopupToElem: null,
169
+
170
+ lastSTime: 0,
171
+
172
+ // isCustomDragStatus: false,
173
+
174
+ inited: false,
175
+ tooltipTimeout: null,
176
+ initStatus: false,
177
+ isActivated: false,
178
+
179
+ // keyCtxTimeout: undefined,
180
+
181
+ // 刷新布局
182
+ // rceTimeout: undefined,
183
+ // rceRunTime: undefined,
184
+ rceDelay: 0
185
+
186
+ // rsePending: false,
187
+
188
+ // 滚动属性
189
+ // intoRunScroll: false,
190
+ // inVirtualScroll: false,
191
+ // inWheelScroll: false,
192
+
193
+ // inHeaderScroll: false,
194
+ // inBodyScroll: false,
195
+ // inFooterScroll: false,
196
+ // scrollRenderType?: '',
197
+
198
+ // isSyncGanttScrollTop: false,
199
+
200
+ // 同步滚动
201
+ // lcsTimeout: undefined,
202
+ // lcsRunTime: undefined,
203
+
204
+ // 横向虚拟
205
+ // lxRunTime: undefined,
206
+ // lxTimeout: undefined,
207
+ // 纵向虚拟
208
+ // lyRunTime: undefined,
209
+ // lyTimeout: undefined,
210
+
211
+ // 动态高度
212
+ // chRunTime: undefined,
213
+ // chTimeout: undefined,
214
+
215
+ // isResizeCellHeight: false,
216
+
217
+ // _sToTime: null
218
+ }
219
+ }
220
+
221
+ export function createReactData(): TableReactData {
222
+ return {
223
+ updateColFlag: 0,
224
+ // 低性能的静态列
225
+ staticColumns: [],
226
+ // 渲染的列分组
227
+ tableGroupColumn: [],
228
+ // 可视区渲染的列
229
+ tableColumn: [],
230
+ // 渲染中的数据
231
+ tableData: [],
232
+ // 是否启用了横向 X 可视渲染方式加载
233
+ scrollXLoad: false,
234
+ // 是否启用了纵向 Y 可视渲染方式加载
235
+ scrollYLoad: false,
236
+ // 是否存在纵向滚动条
237
+ overflowY: true,
238
+ // 是否存在横向滚动条
239
+ overflowX: false,
240
+ // 纵向滚动条的宽度
241
+ scrollbarWidth: 0,
242
+ // 横向滚动条的高度
243
+ scrollbarHeight: 0,
244
+
245
+ // 滚动条
246
+ yThumbHeight: 0,
247
+ xThumbWidth: 0,
248
+
249
+ // 行高
250
+ rowHeight: 0,
251
+ // 表格父容器的高度
252
+ parentHeight: 0,
253
+ // 是否使用分组表头
254
+ isGroup: false,
255
+ isAllOverflow: false,
256
+ // 复选框属性,是否全选
257
+ isAllSelected: false,
258
+ // 复选框属性,有选中且非全选状态
259
+ isIndeterminate: false,
260
+ // 单选框属性,选中行
261
+ selectRadioRow: null,
262
+ // 表尾合计数据
263
+ footerTableData: [],
264
+ // 行分组列信息
265
+ rowGroupColumn: null,
266
+ // 展开列信息
267
+ expandColumn: null,
268
+ checkboxColumn: null,
269
+ radioColumn: null,
270
+ // 树节点列信息
271
+ treeNodeColumn: null,
272
+ hasFixedColumn: false,
273
+ // 刷新列标识,当列筛选被改变时,触发表格刷新数据
274
+ upDataFlag: 0,
275
+ // 刷新列标识,当列的特定属性被改变时,触发表格刷新列
276
+ reColumnFlag: 0,
277
+ // 初始化标识
278
+ initStore: {
279
+ filter: false,
280
+ import: false,
281
+ export: false,
282
+ custom: false
283
+ },
284
+ // 自定义列相关的信息
285
+ customStore: {
286
+ btnEl: null,
287
+ isAll: false,
288
+ isIndeterminate: false,
289
+ activeBtn: false,
290
+ activeWrapper: false,
291
+ visible: false,
292
+ maxHeight: null,
293
+ defPopupStyle: {},
294
+ panePopupStyle: {},
295
+ oldSortMaps: {},
296
+ oldFixedMaps: {},
297
+ oldVisibleMaps: {}
298
+ },
299
+ customColumnList: [],
300
+ // 当前选中的筛选列
301
+ filterStore: {
302
+ targetEl: null,
303
+ isAllSelected: false,
304
+ isIndeterminate: false,
305
+ style: null,
306
+ column: null,
307
+ visible: false
308
+ },
309
+ // 存放列相关的信息
310
+ columnStore: {
311
+ leftList: [],
312
+ centerList: [],
313
+ rightList: [],
314
+ resizeList: [],
315
+ pxList: [],
316
+ pxMinList: [],
317
+ autoMinList: [],
318
+ scaleList: [],
319
+ scaleMinList: [],
320
+ autoList: [],
321
+ remainList: []
322
+ },
323
+ // 存放快捷菜单的信息
324
+ ctxMenuStore: {
325
+ selected: null,
326
+ visible: false,
327
+ showChild: false,
328
+ selectChild: null,
329
+ list: [],
330
+ style: null
331
+ },
332
+ // 存放可编辑相关信息
333
+ editStore: {
334
+ indexs: {
335
+ columns: []
336
+ },
337
+ titles: {
338
+ columns: []
339
+ },
340
+ // 选中源
341
+ selected: {
342
+ row: null,
343
+ column: null
344
+ },
345
+ // 已复制源
346
+ copyed: {
347
+ cut: false,
348
+ rows: [],
349
+ columns: []
350
+ },
351
+ // 激活
352
+ actived: {
353
+ row: null,
354
+ column: null
355
+ },
356
+ // 当前被强制聚焦单元格,只会在鼠标点击后算聚焦
357
+ focused: {
358
+ row: null,
359
+ column: null
360
+ }
361
+ },
362
+ // 存放 tooltip 相关信息
363
+ tooltipStore: {
364
+ row: null,
365
+ column: null,
366
+ content: '',
367
+ visible: false,
368
+ type: null,
369
+ currOpts: {}
370
+ },
371
+ // 存放数据校验相关信息
372
+ validStore: {
373
+ visible: false
374
+ },
375
+ validErrorMaps: {},
376
+ // 导入相关信息
377
+ importStore: {
378
+ inited: false,
379
+ file: null,
380
+ type: '',
381
+ modeList: [],
382
+ typeList: [],
383
+ filename: '',
384
+ visible: false
385
+ },
386
+ importParams: {
387
+ mode: '',
388
+ types: null,
389
+ message: true
390
+ },
391
+ // 导出相关信息
392
+ exportStore: {
393
+ inited: false,
394
+ name: '',
395
+ modeList: [],
396
+ typeList: [],
397
+ columns: [],
398
+ isPrint: false,
399
+ hasFooter: false,
400
+ hasMerge: false,
401
+ hasTree: false,
402
+ hasRowGroup: false,
403
+ hasColgroup: false,
404
+ visible: false
405
+ },
406
+ exportParams: {
407
+ filename: '',
408
+ sheetName: '',
409
+ mode: '',
410
+ type: '',
411
+ isColgroup: false,
412
+ isMerge: false,
413
+ isTreeAllExpanded: false,
414
+ isRowGroupAllExpanded: false,
415
+ useStyle: false,
416
+ original: false,
417
+ message: true,
418
+ isHeader: false,
419
+ isTitle: false,
420
+ isFooter: false
421
+ },
422
+
423
+ visiblwRowsFlag: 1,
424
+
425
+ isRowGroupStatus: false,
426
+ rowGroupList: [],
427
+ aggHandleFields: [],
428
+ aggHandleAggColumns: [],
429
+
430
+ rowGroupExpandedFlag: 1,
431
+ rowExpandedFlag: 1,
432
+ treeExpandedFlag: 1,
433
+ updateCheckboxFlag: 1,
434
+ pendingRowFlag: 1,
435
+ insertRowFlag: 1,
436
+ removeRowFlag: 1,
437
+
438
+ mergeHeadFlag: 1,
439
+ mergeBodyFlag: 1,
440
+ mergeFootFlag: 1,
441
+
442
+ rowHeightStore: {
443
+ xlarge: 54,
444
+ large: 52,
445
+ default: 48,
446
+ medium: 44,
447
+ small: 40,
448
+ mini: 36
449
+ },
450
+
451
+ scrollVMLoading: false,
452
+ scrollYHeight: 0,
453
+ scrollYTop: 0,
454
+ isScrollYBig: false,
455
+ scrollXLeft: 0,
456
+ scrollXWidth: 0,
457
+ isScrollXBig: false,
458
+
459
+ lazScrollLoading: false,
460
+
461
+ rowExpandHeightFlag: 1,
462
+ calcCellHeightFlag: 1,
463
+ resizeHeightFlag: 1,
464
+ resizeWidthFlag: 1,
465
+
466
+ isCustomStatus: false,
467
+ isCustomDragStatus: true,
468
+ ctPopupFlag: 1,
469
+
470
+ isCrossDragRow: false,
471
+ dragRow: null,
472
+ isCrossDragCol: false,
473
+ dragCol: null,
474
+ dragTipText: '',
475
+
476
+ isDragResize: false,
477
+ isRowLoading: false,
478
+ isColLoading: false,
479
+
480
+ currColFlag: 1
481
+ }
482
+ }
483
+
484
+ const maxKey = '__max'
485
+
486
+ export function getRowMaxHeight(chRest: Record<string, number>, isForce: boolean) {
487
+ if (isForce || !chRest[maxKey]) {
488
+ let max = 0
489
+ for (const key in chRest) {
490
+ const val = chRest[key]
491
+ if (key !== maxKey && XEUtils.isNumber(val) && val > max) {
492
+ max = val
493
+ }
494
+ }
495
+ chRest[maxKey] = max
496
+ return max
497
+ }
498
+ return chRest[maxKey]
499
+ }
500
+
501
+ const getAllConvertColumns = (columns: any, parentColumn?: any) => {
502
+ const result: any[] = []
503
+ columns.forEach((column: any) => {
504
+ column.parentId = parentColumn ? parentColumn.id : null
505
+ if (column.visible) {
506
+ if (column.children && column.children.length && column.children.some((column: any) => column.visible)) {
507
+ result.push(column)
508
+ result.push(...getAllConvertColumns(column.children, column))
509
+ } else {
510
+ result.push(column)
511
+ }
512
+ }
513
+ })
514
+ return result
515
+ }
516
+
517
+ export const convertHeaderColumnToRows = (originColumns: any): any[][] => {
518
+ let maxLevel = 1
519
+ const traverse = (column: any, parent?: any) => {
520
+ if (parent) {
521
+ column.level = parent.level + 1
522
+ if (maxLevel < column.level) {
523
+ maxLevel = column.level
524
+ }
525
+ }
526
+ if (column.children && column.children.length && column.children.some((column: any) => column.visible)) {
527
+ let colSpan = 0
528
+ column.children.forEach((subColumn: any) => {
529
+ if (subColumn.visible) {
530
+ traverse(subColumn, column)
531
+ colSpan += subColumn.colSpan
532
+ }
533
+ })
534
+ column.colSpan = colSpan
535
+ } else {
536
+ column.colSpan = 1
537
+ }
538
+ }
539
+
540
+ originColumns.forEach((column: any) => {
541
+ column.level = 1
542
+ traverse(column)
543
+ })
544
+
545
+ const rows: any[] = []
546
+ for (let i = 0; i < maxLevel; i++) {
547
+ rows.push([])
548
+ }
549
+
550
+ const allColumns = getAllConvertColumns(originColumns)
551
+
552
+ allColumns.forEach((column) => {
553
+ if (column.children && column.children.length && column.children.some((column: any) => column.visible)) {
554
+ column.rowSpan = 1
555
+ } else {
556
+ column.rowSpan = maxLevel - column.level + 1
557
+ }
558
+ rows[column.level - 1].push(column)
559
+ })
560
+
561
+ return rows
562
+ }
563
+
564
+ export function convertHeaderToGridRows(spanColumns: VxeTableDefines.ColumnInfo[][]) {
565
+ const rSize = spanColumns.length
566
+ const cSize = spanColumns[0].reduce((sum, cell) => sum + cell.colSpan, 0)
567
+
568
+ const occupiedRows: boolean[][] = []
569
+ const fullRows: any[][] = []
570
+ for (let rIndex = 0; rIndex < rSize; rIndex++) {
571
+ const oCols: boolean[] = []
572
+ const dCols: string[] = []
573
+ for (let cIndex = 0; cIndex < cSize; cIndex++) {
574
+ oCols.push(false)
575
+ dCols.push('')
576
+ }
577
+ occupiedRows.push(oCols)
578
+ fullRows.push(dCols)
579
+ }
580
+
581
+ for (let rIndex = 0; rIndex < rSize; rIndex++) {
582
+ let currColIndex = 0
583
+ for (const column of spanColumns[rIndex]) {
584
+ const { colSpan, rowSpan } = column
585
+ let startColIndex = -1
586
+ for (let ccIndex = currColIndex; ccIndex <= cSize - colSpan; ccIndex++) {
587
+ let oFlag = true
588
+ for (let csIndex = 0; csIndex < colSpan; csIndex++) {
589
+ if (occupiedRows[rIndex][ccIndex + csIndex]) {
590
+ oFlag = false
591
+ break
592
+ }
593
+ }
594
+ if (oFlag) {
595
+ startColIndex = ccIndex
596
+ break
597
+ }
598
+ }
599
+ if (startColIndex === -1) {
600
+ for (let j = 0; j <= cSize - colSpan; j++) {
601
+ let oFlag = true
602
+ for (let k = 0; k < colSpan; k++) {
603
+ if (occupiedRows[rIndex][j + k]) {
604
+ oFlag = false
605
+ break
606
+ }
607
+ }
608
+ if (oFlag) {
609
+ startColIndex = j
610
+ break
611
+ }
612
+ }
613
+ if (startColIndex === -1) {
614
+ // error
615
+ break
616
+ }
617
+ }
618
+
619
+ for (let srIndex = rIndex; srIndex < rIndex + rowSpan; srIndex++) {
620
+ for (let scIndex = startColIndex; scIndex < startColIndex + colSpan; scIndex++) {
621
+ occupiedRows[srIndex][scIndex] = true
622
+ fullRows[srIndex][scIndex] = column
623
+ }
624
+ }
625
+ currColIndex = startColIndex + colSpan
626
+ }
627
+ }
628
+ return fullRows
629
+ }
630
+
631
+ export function restoreScrollLocation($xeTable: VxeTableConstructor, scrollLeft: number, scrollTop: number) {
632
+ const internalData = $xeTable.internalData
633
+
634
+ if (scrollLeft || scrollTop) {
635
+ internalData.intoRunScroll = false
636
+ internalData.inVirtualScroll = false
637
+ internalData.inWheelScroll = false
638
+ internalData.inHeaderScroll = false
639
+ internalData.inBodyScroll = false
640
+ internalData.inFooterScroll = false
641
+ internalData.scrollRenderType = ''
642
+ // 还原滚动状态
643
+ return $xeTable.scrollTo(scrollLeft, scrollTop)
644
+ }
645
+ return $xeTable.clearScroll()
646
+ }
647
+
648
+ export function getRowUniqueId() {
649
+ return XEUtils.uniqueId('row_')
650
+ }
651
+
652
+ /**
653
+ * 生成行的唯一主键
654
+ */
655
+ export function createRowId(rowOpts: VxeTablePropTypes.RowConfig, row: any, keyField: string) {
656
+ const { createKeyMethod } = rowOpts
657
+ if (createKeyMethod) {
658
+ return createKeyMethod({ row, keyField })
659
+ }
660
+ return getRowUniqueId()
661
+ }
662
+
663
+ export function hasDeepKey(rowKey: string) {
664
+ return rowKey.indexOf('.') > -1
665
+ }
666
+
667
+ // 行主键 key
668
+ export function getRowkey($xeTable: VxeTableConstructor) {
669
+ const { currKeyField } = $xeTable.internalData
670
+ return currKeyField
671
+ }
672
+
673
+ // 行主键 value
674
+ export function getRowid($xeTable: VxeTableConstructor, row: any) {
675
+ const internalData = $xeTable.internalData
676
+ const { isCurrDeepKey, currKeyField } = internalData
677
+ return row ? encodeRowid((isCurrDeepKey ? getDeepRowIdByKey : getFastRowIdByKey)(row, currKeyField)) : ''
678
+ }
679
+
680
+ export function createHandleUpdateRowId($xeTable: VxeTableConstructor) {
681
+ const internalData = $xeTable.internalData
682
+ const { isCurrDeepKey, currKeyField } = internalData
683
+ const { computeRowOpts } = $xeTable.getComputeMaps()
684
+ const rowOpts = computeRowOpts.value
685
+ const updateRId = isCurrDeepKey ? updateDeepRowKey : updateFastRowKey
686
+ return {
687
+ rowKey: currKeyField,
688
+ handleUpdateRowId(row: any) {
689
+ return row ? updateRId(rowOpts, row, currKeyField) : ''
690
+ }
691
+ }
692
+ }
693
+
694
+ export function createHandleGetRowId($xeTable: VxeTableConstructor) {
695
+ const internalData = $xeTable.internalData
696
+ const { isCurrDeepKey, currKeyField } = internalData
697
+ const getRId = isCurrDeepKey ? getDeepRowIdByKey : getFastRowIdByKey
698
+ return {
699
+ rowKey: currKeyField,
700
+ handleGetRowId(row: any) {
701
+ return row ? encodeRowid(getRId(row, currKeyField)) : ''
702
+ }
703
+ }
704
+ }
705
+
706
+ // 编码行主键
707
+ export function encodeRowid(rowVal: string | number) {
708
+ return XEUtils.eqNull(rowVal) ? '' : encodeURIComponent(rowVal)
709
+ }
710
+
711
+ function getDeepRowIdByKey(row: any, rowKey: string | number) {
712
+ return XEUtils.get(row, rowKey)
713
+ }
714
+
715
+ function updateDeepRowKey(rowOpts: VxeTablePropTypes.RowConfig, row: any, rowKey: string) {
716
+ let rowid = encodeRowid(getDeepRowIdByKey(row, rowKey))
717
+ if (eqEmptyValue(rowid)) {
718
+ const newRowid = createRowId(rowOpts, row, rowKey)
719
+ rowid = '' + newRowid
720
+ XEUtils.set(row, rowKey, rowid)
721
+ }
722
+ return rowid
723
+ }
724
+
725
+ function getFastRowIdByKey(row: any, rowKey: string) {
726
+ return row[rowKey]
727
+ }
728
+
729
+ function updateFastRowKey(rowOpts: VxeTablePropTypes.RowConfig, row: any, rowKey: string) {
730
+ let rowid = encodeRowid(getFastRowIdByKey(row, rowKey))
731
+ if (eqEmptyValue(rowid)) {
732
+ const newRowid = createRowId(rowOpts, row, rowKey)
733
+ rowid = '' + newRowid
734
+ row[rowKey] = newRowid
735
+ }
736
+ return rowid
737
+ }
738
+
739
+ export interface XEColumnInstance {
740
+ columnConfig: ColumnInfo
741
+ }
742
+
743
+ export function handleFieldOrColumn($xeTable: VxeTableConstructor, fieldOrColumn: string | VxeTableDefines.ColumnInfo | null) {
744
+ if (fieldOrColumn) {
745
+ return XEUtils.isString(fieldOrColumn) || XEUtils.isNumber(fieldOrColumn) ? $xeTable.getColumnByField(`${fieldOrColumn}`) : fieldOrColumn
746
+ }
747
+ return null
748
+ }
749
+
750
+ export function handleRowidOrRow($xeTable: VxeTableConstructor, rowidOrRow: any) {
751
+ if (rowidOrRow) {
752
+ const rowid = XEUtils.isString(rowidOrRow) || XEUtils.isNumber(rowidOrRow) ? rowidOrRow : getRowid($xeTable, rowidOrRow)
753
+ return $xeTable.getRowById(rowid)
754
+ }
755
+ return null
756
+ }
757
+
758
+ export function getCellRestHeight(rowRest: VxeTableDefines.RowCacheItem, cellOpts: VxeTablePropTypes.CellConfig, rowOpts: VxeTablePropTypes.RowConfig, defaultRowHeight: number) {
759
+ const { height, minHeight, maxHeight } = cellOpts
760
+ let cellHeight = rowRest.resizeHeight || height || rowOpts.height || rowRest.height || defaultRowHeight
761
+ if (maxHeight && maxHeight <= cellHeight) {
762
+ cellHeight = maxHeight
763
+ }
764
+ if (minHeight && minHeight >= cellHeight) {
765
+ cellHeight = minHeight
766
+ }
767
+ return cellHeight
768
+ }
769
+
770
+ function getPaddingLeftRightSize(elem: HTMLElement | null) {
771
+ if (elem) {
772
+ const computedStyle = getComputedStyle(elem)
773
+ const paddingLeft = XEUtils.toNumber(computedStyle.paddingLeft)
774
+ const paddingRight = XEUtils.toNumber(computedStyle.paddingRight)
775
+ return paddingLeft + paddingRight
776
+ }
777
+ return 0
778
+ }
779
+
780
+ function getElementMarginAndWidth(elem: HTMLElement | null) {
781
+ if (elem) {
782
+ const computedStyle = getComputedStyle(elem)
783
+ const marginLeft = XEUtils.toNumber(computedStyle.marginLeft)
784
+ const marginRight = XEUtils.toNumber(computedStyle.marginRight)
785
+ return elem.offsetWidth + marginLeft + marginRight
786
+ }
787
+ return 0
788
+ }
789
+
790
+ export function toFilters(filters: any, colid?: string | number) {
791
+ if (filters) {
792
+ if (XEUtils.isArray(filters)) {
793
+ return filters.map(({ label, value, data, resetValue, checked }) => {
794
+ return { label, value, data, resetValue, checked: !!checked, _checked: !!checked, _colId: colid }
795
+ })
796
+ }
797
+ return []
798
+ }
799
+ return filters
800
+ }
801
+
802
+ export function toTreePathSeq(path: any[]) {
803
+ return path.map((num, i) => (i % 2 === 0 ? Number(num) + 1 : '.')).join('')
804
+ }
805
+
806
+ export function getCellValue(row: any, column: VxeTableDefines.ColumnInfo | null) {
807
+ if (column) {
808
+ return XEUtils.get(row, column.field)
809
+ }
810
+ return null
811
+ }
812
+
813
+ export function setCellValue(row: any, column: VxeTableDefines.ColumnInfo | null, value: any) {
814
+ if (column) {
815
+ XEUtils.set(row, column.field, value)
816
+ }
817
+ }
818
+
819
+ export function getRefElem(refEl: any) {
820
+ if (refEl) {
821
+ const rest = refEl.value
822
+ if (rest) {
823
+ return (rest.$el || rest) as HTMLElement
824
+ }
825
+ }
826
+ return null
827
+ }
828
+
829
+ export function getCalcHeight(height: number | 'unset' | undefined | null) {
830
+ if (height === 'unset') {
831
+ return 0
832
+ }
833
+ return height || 0
834
+ }
835
+
836
+ /**
837
+ * 列宽拖动最大宽度
838
+ */
839
+ export function getColReMaxWidth(params: (VxeTableDefines.CellRenderHeaderParams | VxeTableDefines.CellRenderBodyParams | VxeTableDefines.CellRenderFooterParams) & { cell: HTMLTableCellElement }) {
840
+ const { $table, column, cell } = params
841
+ const internalData = $table.internalData
842
+ const { elemStore } = internalData
843
+ const { computeColumnOpts, computeResizableOpts } = $table.getComputeMaps()
844
+ const resizableOpts = computeResizableOpts.value
845
+ const columnOpts = computeColumnOpts.value
846
+ const { maxWidth: reMaxWidth } = resizableOpts
847
+ const colMaxWidth = column.maxWidth || columnOpts.maxWidth
848
+ // 如果自定义调整宽度逻辑
849
+ if (reMaxWidth) {
850
+ const customMaxWidth = XEUtils.isFunction(reMaxWidth) ? reMaxWidth(params) : reMaxWidth
851
+ if (customMaxWidth !== 'auto') {
852
+ return Math.max(1, XEUtils.toNumber(customMaxWidth))
853
+ }
854
+ }
855
+ const minTitleWidth = XEUtils.floor((XEUtils.toNumber(getComputedStyle(cell).fontSize) || 14) * 1.8)
856
+ const paddingLeftRight = getPaddingLeftRightSize(cell) + getPaddingLeftRightSize(queryElement(cell, '.vxe-cell'))
857
+ const mWidth = minTitleWidth + paddingLeftRight
858
+ // 如果设置最小宽
859
+ if (colMaxWidth) {
860
+ const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
861
+ if (bodyScrollElem) {
862
+ if (isScale(colMaxWidth)) {
863
+ const bodyWidth = bodyScrollElem.clientWidth - 1
864
+ const meanWidth = bodyWidth / 100
865
+ return Math.max(mWidth, Math.floor(XEUtils.toInteger(colMaxWidth) * meanWidth))
866
+ } else if (isPx(colMaxWidth)) {
867
+ return Math.max(mWidth, XEUtils.toInteger(colMaxWidth))
868
+ }
869
+ }
870
+ }
871
+ return -1
872
+ }
873
+
874
+ /**
875
+ * 列宽拖动最小宽度
876
+ */
877
+ export function getColReMinWidth(params: (VxeTableDefines.CellRenderHeaderParams | VxeTableDefines.CellRenderBodyParams | VxeTableDefines.CellRenderFooterParams) & { cell: HTMLTableCellElement }) {
878
+ const { $table, column, cell } = params
879
+ const tableProps = $table.props
880
+ const internalData = $table.internalData
881
+ const { computeColumnOpts, computeResizableOpts } = $table.getComputeMaps()
882
+ const resizableOpts = computeResizableOpts.value
883
+ const columnOpts = computeColumnOpts.value
884
+ const { minWidth: reMinWidth } = resizableOpts
885
+ // 如果自定义调整宽度逻辑
886
+ if (reMinWidth) {
887
+ const customMinWidth = XEUtils.isFunction(reMinWidth) ? reMinWidth(params) : reMinWidth
888
+ if (customMinWidth !== 'auto') {
889
+ return Math.max(1, XEUtils.toNumber(customMinWidth))
890
+ }
891
+ }
892
+ const { elemStore } = internalData
893
+ const { showHeaderOverflow: allColumnHeaderOverflow } = tableProps
894
+ const { showHeaderOverflow } = column
895
+ const colMinWidth = column.minWidth || columnOpts.minWidth
896
+ const headOverflow = XEUtils.isUndefined(showHeaderOverflow) || XEUtils.isNull(showHeaderOverflow) ? allColumnHeaderOverflow : showHeaderOverflow
897
+ const showEllipsis = headOverflow === 'ellipsis'
898
+ const showTitle = headOverflow === 'title'
899
+ const showTooltip = headOverflow === true || headOverflow === 'tooltip'
900
+ const hasEllipsis = showTitle || showTooltip || showEllipsis
901
+ const minTitleWidth = XEUtils.floor((XEUtils.toNumber(getComputedStyle(cell).fontSize) || 14) * 1.8)
902
+ const paddingLeftRight = getPaddingLeftRightSize(cell) + getPaddingLeftRightSize(queryElement(cell, '.vxe-cell'))
903
+ let mWidth = minTitleWidth + paddingLeftRight
904
+ // 默认最小宽处理
905
+ if (hasEllipsis) {
906
+ const dragIconWidth = getElementMarginAndWidth(queryElement(cell, '.vxe-cell--drag-handle'))
907
+ const checkboxIconWidth = getElementMarginAndWidth(queryElement(cell, '.vxe-cell--checkbox'))
908
+ const requiredIconWidth = getElementMarginAndWidth(queryElement(cell, '.vxe-cell--required-icon'))
909
+ const editIconWidth = getElementMarginAndWidth(queryElement(cell, '.vxe-cell--edit-icon'))
910
+ const prefixIconWidth = getElementMarginAndWidth(queryElement(cell, '.vxe-cell-title-prefix-icon'))
911
+ const suffixIconWidth = getElementMarginAndWidth(queryElement(cell, '.vxe-cell-title-suffix-icon'))
912
+ const sortIconWidth = getElementMarginAndWidth(queryElement(cell, '.vxe-cell--sort'))
913
+ const filterIconWidth = getElementMarginAndWidth(queryElement(cell, '.vxe-cell--filter'))
914
+ mWidth += dragIconWidth + checkboxIconWidth + requiredIconWidth + editIconWidth + prefixIconWidth + suffixIconWidth + filterIconWidth + sortIconWidth
915
+ }
916
+ // 如果设置最小宽
917
+ if (colMinWidth) {
918
+ const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
919
+ if (bodyScrollElem) {
920
+ if (isScale(colMinWidth)) {
921
+ const bodyWidth = bodyScrollElem.clientWidth - 1
922
+ const meanWidth = bodyWidth / 100
923
+ return Math.max(mWidth, Math.floor(XEUtils.toInteger(colMinWidth) * meanWidth))
924
+ } else if (isPx(colMinWidth)) {
925
+ return Math.max(mWidth, XEUtils.toInteger(colMinWidth))
926
+ }
927
+ }
928
+ }
929
+ return mWidth
930
+ }
931
+
932
+ export function isColumnInfo(column: any): column is ColumnInfo {
933
+ return column && (column.constructor === ColumnInfo || column instanceof ColumnInfo)
934
+ }
935
+
936
+ // 获取所有的列,排除分组
937
+ export function getColumnList(columns: VxeTableDefines.ColumnInfo[]) {
938
+ const result: VxeTableDefines.ColumnInfo[] = []
939
+ columns.forEach((column) => {
940
+ result.push(...(column.children && column.children.length ? getColumnList(column.children) : [column]))
941
+ })
942
+ return result
943
+ }
944
+
945
+ export function createColumn($xeTable: VxeTableConstructor & VxeTablePrivateMethods, options: VxeTableDefines.ColumnOptions | VxeTableDefines.ColumnInfo, renderOptions: any): any {
946
+ return isColumnInfo(options) ? options : reactive(new ColumnInfo($xeTable, options, renderOptions))
947
+ }
948
+
949
+ export function watchColumn($xeTable: VxeTableConstructor & VxeTablePrivateMethods, props: any, column: ColumnInfo) {
950
+ Object.keys(props).forEach((name) => {
951
+ watch(
952
+ () => props[name],
953
+ (value: any) => {
954
+ column.update(name, value)
955
+ if ($xeTable) {
956
+ if (name === 'filters') {
957
+ $xeTable.setFilter(column as any, value)
958
+ $xeTable.handleUpdateDataQueue()
959
+ } else if (['visible', 'fixed', 'width', 'minWidth', 'maxWidth'].includes(name)) {
960
+ $xeTable.handleRefreshColumnQueue()
961
+ }
962
+ }
963
+ }
964
+ )
965
+ })
966
+ }
967
+
968
+ export function assembleColumn($xeTable: VxeTableConstructor & VxeTablePrivateMethods, elem: HTMLElement, column: ColumnInfo, colgroup: XEColumnInstance | null) {
969
+ const { reactData } = $xeTable
970
+ const { staticColumns } = reactData
971
+ const parentElem = elem.parentNode
972
+ const parentColumn = colgroup ? colgroup.columnConfig : null
973
+ const parentCols = parentColumn ? parentColumn.children : staticColumns
974
+ if (parentElem && parentCols) {
975
+ column.defaultParentId = parentColumn ? parentColumn.id : null
976
+ parentCols.splice(XEUtils.arrayIndexOf(parentElem.children, elem), 0, column)
977
+ reactData.staticColumns = staticColumns.slice(0)
978
+ }
979
+ }
980
+
981
+ export function destroyColumn($xeTable: VxeTableConstructor & VxeTablePrivateMethods, column: ColumnInfo) {
982
+ const { reactData } = $xeTable
983
+ const { staticColumns } = reactData
984
+ const matchObj = XEUtils.findTree(staticColumns, (item) => item.id === column.id, { children: 'children' })
985
+ if (matchObj) {
986
+ matchObj.items.splice(matchObj.index, 1)
987
+ }
988
+ reactData.staticColumns = staticColumns.slice(0)
989
+ }
990
+
991
+ export function getRootColumn($xeTable: VxeTableConstructor & VxeTablePrivateMethods, column: ColumnInfo) {
992
+ const { internalData } = $xeTable
993
+
994
+ const { fullColumnIdData } = internalData
995
+ if (!column) {
996
+ return null
997
+ }
998
+ let parentColId = column.parentId
999
+ while (fullColumnIdData[parentColId]) {
1000
+ const column = fullColumnIdData[parentColId].column
1001
+ parentColId = column.parentId
1002
+ if (!parentColId) {
1003
+ return column
1004
+ }
1005
+ }
1006
+ return column
1007
+ }
1008
+
1009
+ export function getFirstChildColumn(column: VxeTableDefines.ColumnInfo): VxeTableDefines.ColumnInfo {
1010
+ const { children } = column
1011
+ if (children && children.length) {
1012
+ return getFirstChildColumn(XEUtils.first(children))
1013
+ }
1014
+ return column
1015
+ }
1016
+
1017
+ export function getLastChildColumn(column: VxeTableDefines.ColumnInfo): VxeTableDefines.ColumnInfo {
1018
+ const { children } = column
1019
+ if (children && children.length) {
1020
+ return getFirstChildColumn(XEUtils.last(children))
1021
+ }
1022
+ return column
1023
+ }
1024
+
1025
+ export function clearTableDefaultStatus($xeTable: VxeTableConstructor & VxeTablePrivateMethods) {
1026
+ const { props, internalData } = $xeTable
1027
+
1028
+ const { keyboardConfig, mouseConfig } = props
1029
+ const { computeMouseOpts, computeKeyboardOpts } = $xeTable.getComputeMaps()
1030
+ const mouseOpts = computeMouseOpts.value
1031
+ const keyboardOpts = computeKeyboardOpts.value
1032
+ internalData.initStatus = false
1033
+ const actionList = [
1034
+ $xeTable.clearSort(),
1035
+ $xeTable.clearCurrentRow(),
1036
+ $xeTable.clearCurrentColumn(),
1037
+ $xeTable.clearRadioRow(),
1038
+ $xeTable.clearRadioReserve(),
1039
+ $xeTable.clearCheckboxRow(),
1040
+ $xeTable.clearCheckboxReserve(),
1041
+ $xeTable.clearRowExpand(),
1042
+ $xeTable.clearTreeExpand(),
1043
+ $xeTable.clearTreeExpandReserve(),
1044
+ $xeTable.clearPendingRow()
1045
+ ]
1046
+ if ($xeTable.clearFilter) {
1047
+ actionList.push($xeTable.clearFilter())
1048
+ }
1049
+ if ($xeTable.clearSelected && (hasEnableConf(keyboardConfig, keyboardOpts) || hasEnableConf(mouseConfig, mouseOpts))) {
1050
+ actionList.push($xeTable.clearSelected())
1051
+ }
1052
+ if ($xeTable.clearCellAreas && hasEnableConf(mouseConfig, mouseOpts)) {
1053
+ actionList.push($xeTable.clearCellAreas(), $xeTable.clearCopyCellArea())
1054
+ }
1055
+ return Promise.all(actionList).then(() => {
1056
+ return $xeTable.clearScroll()
1057
+ })
1058
+ }
1059
+
1060
+ export function clearTableAllStatus($xeTable: VxeTableConstructor & VxeTablePrivateMethods) {
1061
+ if ($xeTable.clearFilter) {
1062
+ $xeTable.clearFilter()
1063
+ }
1064
+ return clearTableDefaultStatus($xeTable)
1065
+ }
1066
+
1067
+ export function rowToVisible($xeTable: VxeTableConstructor & VxeTablePrivateMethods, row: any) {
1068
+ const reactData = $xeTable.reactData
1069
+ const internalData = $xeTable.internalData
1070
+
1071
+ const { computeLeftFixedWidth, computeRightFixedWidth, computeRowOpts, computeCellOpts, computeDefaultRowHeight } = $xeTable.getComputeMaps()
1072
+ const { scrollYLoad, scrollYTop, isAllOverflow } = reactData
1073
+ const { elemStore, afterFullData, fullAllDataRowIdData, isResizeCellHeight } = internalData
1074
+ const rowOpts = computeRowOpts.value
1075
+ const cellOpts = computeCellOpts.value
1076
+ const defaultRowHeight = computeDefaultRowHeight.value
1077
+ const leftFixedWidth = computeLeftFixedWidth.value
1078
+ const rightFixedWidth = computeRightFixedWidth.value
1079
+ const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
1080
+ const rowid = getRowid($xeTable, row)
1081
+ if (bodyScrollElem) {
1082
+ const bodyHeight = bodyScrollElem.clientHeight
1083
+ const bodyScrollTop = bodyScrollElem.scrollTop
1084
+ const trElem: HTMLTableRowElement | null = bodyScrollElem.querySelector(`[rowid="${rowid}"]`)
1085
+ if (trElem) {
1086
+ const trOffsetTop = trElem.offsetTop + (scrollYLoad ? scrollYTop : 0)
1087
+ const trHeight = trElem.clientHeight
1088
+ // 检测行是否在可视区中
1089
+ if (trOffsetTop < bodyScrollTop || trOffsetTop > bodyScrollTop + bodyHeight) {
1090
+ return $xeTable.scrollTo(null, trOffsetTop)
1091
+ } else if (trOffsetTop + trHeight >= bodyHeight + bodyScrollTop) {
1092
+ return $xeTable.scrollTo(null, bodyScrollTop + trHeight)
1093
+ }
1094
+ } else {
1095
+ // 如果是虚拟渲染滚动
1096
+ if (scrollYLoad) {
1097
+ const isCustomCellHeight = isResizeCellHeight || cellOpts.height || rowOpts.height
1098
+ if (!isCustomCellHeight && isAllOverflow) {
1099
+ return $xeTable.scrollTo(null, ($xeTable.findRowIndexOf(afterFullData, row) - 1) * defaultRowHeight)
1100
+ }
1101
+ const rowRest = fullAllDataRowIdData[rowid] || {}
1102
+ const rHeight = rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight
1103
+ const scrollTop = rowRest.oTop
1104
+ if (scrollTop < bodyScrollTop) {
1105
+ return $xeTable.scrollTo(null, scrollTop - leftFixedWidth - 1)
1106
+ }
1107
+ return $xeTable.scrollTo(null, scrollTop + rHeight - (bodyHeight - rightFixedWidth - 1))
1108
+ }
1109
+ }
1110
+ }
1111
+ return Promise.resolve()
1112
+ }
1113
+
1114
+ export function colToVisible($xeTable: VxeTableConstructor & VxeTablePrivateMethods, isForce: boolean, column: VxeTableDefines.ColumnInfo, row?: any) {
1115
+ const reactData = $xeTable.reactData
1116
+ const internalData = $xeTable.internalData
1117
+
1118
+ const { computeLeftFixedWidth, computeRightFixedWidth } = $xeTable.getComputeMaps()
1119
+ const { scrollXLoad, scrollXLeft } = reactData
1120
+ const { elemStore, visibleColumn } = internalData
1121
+ const leftFixedWidth = computeLeftFixedWidth.value
1122
+ const rightFixedWidth = computeRightFixedWidth.value
1123
+ const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
1124
+ if (column.fixed) {
1125
+ return Promise.resolve()
1126
+ }
1127
+ if (bodyScrollElem) {
1128
+ const bodyWidth = bodyScrollElem.clientWidth
1129
+ const bodyScrollLeft = bodyScrollElem.scrollLeft
1130
+ let tdElem: HTMLTableCellElement | null = null
1131
+ if (row) {
1132
+ const rowid = getRowid($xeTable, row)
1133
+ tdElem = bodyScrollElem.querySelector(`[rowid="${rowid}"] .${column.id}`)
1134
+ }
1135
+ if (!tdElem) {
1136
+ tdElem = bodyScrollElem.querySelector(`.${column.id}`)
1137
+ }
1138
+ if (tdElem) {
1139
+ const tdOffsetLeft = tdElem.offsetLeft + (scrollXLoad ? scrollXLeft : 0)
1140
+ const cellWidth = tdElem.clientWidth
1141
+ // 检测是否在可视区中
1142
+ if (isForce || (!(tdOffsetLeft <= bodyScrollLeft + leftFixedWidth && tdOffsetLeft + cellWidth > bodyScrollLeft + leftFixedWidth) && !(tdOffsetLeft >= bodyScrollLeft + leftFixedWidth && tdOffsetLeft < bodyScrollLeft + bodyWidth - rightFixedWidth))) {
1143
+ if (tdOffsetLeft < bodyScrollLeft + leftFixedWidth) {
1144
+ return $xeTable.scrollTo(tdOffsetLeft - leftFixedWidth - 1)
1145
+ } else if (tdOffsetLeft + cellWidth - bodyScrollLeft > bodyWidth - rightFixedWidth) {
1146
+ return $xeTable.scrollTo(tdOffsetLeft + cellWidth - (bodyWidth - rightFixedWidth - 1))
1147
+ }
1148
+ }
1149
+ } else {
1150
+ if (scrollXLoad) {
1151
+ let tdOffsetLeft = 0
1152
+ const cellWidth = column.renderWidth
1153
+ for (let i = 0; i < visibleColumn.length; i++) {
1154
+ const currCol = visibleColumn[i]
1155
+ if (currCol === column || currCol.id === column.id) {
1156
+ break
1157
+ }
1158
+ tdOffsetLeft += currCol.renderWidth
1159
+ }
1160
+ // 检测是否在可视区中
1161
+ if (isForce || (!(tdOffsetLeft <= bodyScrollLeft + leftFixedWidth && tdOffsetLeft + cellWidth > bodyScrollLeft + leftFixedWidth) && !(tdOffsetLeft >= bodyScrollLeft + leftFixedWidth && tdOffsetLeft < bodyScrollLeft + bodyWidth - rightFixedWidth))) {
1162
+ if (tdOffsetLeft < bodyScrollLeft) {
1163
+ return $xeTable.scrollTo(tdOffsetLeft - leftFixedWidth - 1)
1164
+ }
1165
+ return $xeTable.scrollTo(tdOffsetLeft + cellWidth - (bodyWidth - rightFixedWidth - 1))
1166
+ }
1167
+ }
1168
+ }
1169
+ }
1170
+ return Promise.resolve()
1171
+ }
1172
+
1173
+ function hangleBolleanDefaultValue(currVal: boolean | null | undefined, defVal: boolean | null | undefined) {
1174
+ return XEUtils.isBoolean(currVal) ? currVal : defVal
1175
+ }
1176
+
1177
+ export function handleCustomStoreConfig($xeTable: VxeTableConstructor) {
1178
+ const { computeCustomOpts } = $xeTable.getComputeMaps()
1179
+ const customOpts = computeCustomOpts.value
1180
+ const { storage, storeOptions } = customOpts
1181
+
1182
+ const isAllCustom = storage === true
1183
+ const storageOpts: VxeTableDefines.VxeTableCustomStorageObj = Object.assign({}, isAllCustom ? {} : storage || {}, storeOptions)
1184
+ const isCustomAlign = hangleBolleanDefaultValue(storageOpts.align, isAllCustom)
1185
+ const isCustomHeaderAlign = hangleBolleanDefaultValue(storageOpts.headerAlign, isAllCustom)
1186
+ const isCustomFooterAlign = hangleBolleanDefaultValue(storageOpts.footerAlign, isAllCustom)
1187
+ const isCustomResizable = hangleBolleanDefaultValue(storageOpts.resizable, isAllCustom)
1188
+ const isCustomVisible = hangleBolleanDefaultValue(storageOpts.visible, isAllCustom)
1189
+ const isCustomFixed = hangleBolleanDefaultValue(storageOpts.fixed, isAllCustom)
1190
+ const isCustomSort = hangleBolleanDefaultValue(storageOpts.sort, isAllCustom)
1191
+ const isCustomAggGroup = hangleBolleanDefaultValue(storageOpts.aggGroup, isAllCustom)
1192
+ const isCustomAggFunc = hangleBolleanDefaultValue(storageOpts.aggFunc, isAllCustom)
1193
+ const isCustomPager = hangleBolleanDefaultValue(storageOpts.pager, isAllCustom)
1194
+ return {
1195
+ isCustomAlign,
1196
+ isCustomHeaderAlign,
1197
+ isCustomFooterAlign,
1198
+ isCustomResizable,
1199
+ isCustomVisible,
1200
+ isCustomFixed,
1201
+ isCustomSort,
1202
+ isCustomAggGroup,
1203
+ isCustomAggFunc,
1204
+ isCustomPager
1205
+ }
1206
+ }