vxe-table 4.18.4 → 4.18.6

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