stk-table-vue 0.0.2 → 0.1.0

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.
package/lib/style.css CHANGED
@@ -5,6 +5,7 @@
5
5
  }
6
6
  .stk-table{
7
7
  --row-height:28px;
8
+ --header-row-height:var(--row-height);
8
9
  --cell-padding-x:8px;
9
10
  --resize-handle-width:4px;
10
11
  --border-color:#e8e8f4;
@@ -25,6 +26,8 @@
25
26
  --sort-arrow-active-color:#1b63d9;
26
27
  --sort-arrow-active-sub-color:#cbcbe1;
27
28
  --col-resize-indicator-color:#87879c;
29
+ --fixed-col-shadow-color-from:rgba(0, 0, 0, 0.1);
30
+ --fixed-col-shadow-color-to:rgba(0, 0, 0, 0);
28
31
  position:relative;
29
32
  overflow:auto;
30
33
  display:flex;
@@ -45,6 +48,8 @@
45
48
  --sort-arrow-active-color:#d0d1d2;
46
49
  --sort-arrow-active-sub-color:#5d6064;
47
50
  --col-resize-indicator-color:#5d6064;
51
+ --fixed-col-shadow-color-from:rgba(135, 135, 156, 0.1);
52
+ --fixed-col-shadow-color-to:rgba(135, 135, 156, 0);
48
53
  color:#d1d1e0;
49
54
  }
50
55
  .stk-table.headless{
@@ -132,14 +137,42 @@
132
137
  .stk-table .stk-table-main th,
133
138
  .stk-table .stk-table-main td{
134
139
  z-index:1;
135
- height:var(--row-height);
136
140
  font-size:14px;
137
141
  box-sizing:border-box;
138
142
  padding:0 var(--cell-padding-x);
139
143
  }
144
+ .stk-table .stk-table-main th.fixed-cell--left,
145
+ .stk-table .stk-table-main td.fixed-cell--left{
146
+ --shadow-rotate:90deg;
147
+ }
148
+ .stk-table .stk-table-main th.fixed-cell--left.fixed-cell--shadow::after,
149
+ .stk-table .stk-table-main td.fixed-cell--left.fixed-cell--shadow::after{
150
+ right:-10px;
151
+ }
152
+ .stk-table .stk-table-main th.fixed-cell--right,
153
+ .stk-table .stk-table-main td.fixed-cell--right{
154
+ --shadow-rotate:-90deg;
155
+ }
156
+ .stk-table .stk-table-main th.fixed-cell--right.fixed-cell--shadow::after,
157
+ .stk-table .stk-table-main td.fixed-cell--right.fixed-cell--shadow::after{
158
+ left:-10px;
159
+ }
160
+ .stk-table .stk-table-main th.fixed-cell--shadow::after,
161
+ .stk-table .stk-table-main td.fixed-cell--shadow::after{
162
+ content:'';
163
+ width:10px;
164
+ height:100%;
165
+ top:0px;
166
+ position:absolute;
167
+ pointer-events:none;
168
+ background-image:linear-gradient(var(--shadow-rotate), var(--fixed-col-shadow-color-from), var(--fixed-col-shadow-color-to));
169
+ }
140
170
  .stk-table .stk-table-main th{
141
171
  color:var(--th-color);
142
172
  }
173
+ .stk-table .stk-table-main thead tr{
174
+ height:var(--header-row-height);
175
+ }
143
176
  .stk-table .stk-table-main thead tr:first-child th{
144
177
  position:sticky;
145
178
  top:0;
@@ -158,30 +191,30 @@
158
191
  text-overflow:ellipsis;
159
192
  overflow:hidden;
160
193
  }
161
- .stk-table .stk-table-main thead tr th:not(.sorter-desc):not(.sorter-asc):hover .table-header-cell-wrapper .table-header-sorter #arrow-up{
194
+ .stk-table .stk-table-main thead tr th:not(.sorter-desc):not(.sorter-asc):hover .table-header-cell-wrapper .table-header-sorter .arrow-up{
162
195
  fill:var(--sort-arrow-hover-color);
163
196
  }
164
- .stk-table .stk-table-main thead tr th:not(.sorter-desc):not(.sorter-asc):hover .table-header-cell-wrapper .table-header-sorter #arrow-down{
197
+ .stk-table .stk-table-main thead tr th:not(.sorter-desc):not(.sorter-asc):hover .table-header-cell-wrapper .table-header-sorter .arrow-down{
165
198
  fill:var(--sort-arrow-hover-color);
166
199
  }
167
200
  .stk-table .stk-table-main thead tr th.sorter-desc .table-header-cell-wrapper .table-header-sorter{
168
201
  display:inline;
169
202
  display:initial;
170
203
  }
171
- .stk-table .stk-table-main thead tr th.sorter-desc .table-header-cell-wrapper .table-header-sorter #arrow-up{
204
+ .stk-table .stk-table-main thead tr th.sorter-desc .table-header-cell-wrapper .table-header-sorter .arrow-up{
172
205
  fill:var(--sort-arrow-active-sub-color);
173
206
  }
174
- .stk-table .stk-table-main thead tr th.sorter-desc .table-header-cell-wrapper .table-header-sorter #arrow-down{
207
+ .stk-table .stk-table-main thead tr th.sorter-desc .table-header-cell-wrapper .table-header-sorter .arrow-down{
175
208
  fill:var(--sort-arrow-active-color);
176
209
  }
177
210
  .stk-table .stk-table-main thead tr th.sorter-asc .table-header-cell-wrapper .table-header-sorter{
178
211
  display:inline;
179
212
  display:initial;
180
213
  }
181
- .stk-table .stk-table-main thead tr th.sorter-asc .table-header-cell-wrapper .table-header-sorter #arrow-up{
214
+ .stk-table .stk-table-main thead tr th.sorter-asc .table-header-cell-wrapper .table-header-sorter .arrow-up{
182
215
  fill:var(--sort-arrow-active-color);
183
216
  }
184
- .stk-table .stk-table-main thead tr th.sorter-asc .table-header-cell-wrapper .table-header-sorter #arrow-down{
217
+ .stk-table .stk-table-main thead tr th.sorter-asc .table-header-cell-wrapper .table-header-sorter .arrow-down{
185
218
  fill:var(--sort-arrow-active-sub-color);
186
219
  }
187
220
  .stk-table .stk-table-main thead tr th .table-header-cell-wrapper{
@@ -200,8 +233,8 @@
200
233
  height:16px;
201
234
  display:none;
202
235
  }
203
- .stk-table .stk-table-main thead tr th .table-header-cell-wrapper .table-header-sorter #arrow-up,
204
- .stk-table .stk-table-main thead tr th .table-header-cell-wrapper .table-header-sorter #arrow-down{
236
+ .stk-table .stk-table-main thead tr th .table-header-cell-wrapper .table-header-sorter .arrow-up,
237
+ .stk-table .stk-table-main thead tr th .table-header-cell-wrapper .table-header-sorter .arrow-down{
205
238
  fill:var(--sort-arrow-color);
206
239
  }
207
240
  .stk-table .stk-table-main thead tr th .table-header-cell-wrapper .table-header-resizer{
@@ -219,6 +252,7 @@
219
252
  }
220
253
  .stk-table .stk-table-main tbody tr{
221
254
  background-color:var(--td-bgc);
255
+ height:var(--row-height);
222
256
  }
223
257
  .stk-table .stk-table-main tbody tr.highlight-row{
224
258
  animation:stkTableDim 2s linear;
@@ -265,7 +299,7 @@
265
299
  }
266
300
  .stk-table.virtual .stk-table-main thead tr th .table-header-cell-wrapper{
267
301
  overflow:hidden;
268
- max-height:var(--row-height);
302
+ max-height:var(--header-row-height);
269
303
  }
270
304
  .stk-table.virtual .stk-table-main tbody{
271
305
  position:relative;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stk-table-vue",
3
- "version": "0.0.2",
3
+ "version": "0.1.0",
4
4
  "description": "simple realtime virtual table for vue3",
5
5
  "main": "./lib/stk-table-vue.js",
6
6
  "types": "./lib/StkTable/index.d.ts",
@@ -15,15 +15,15 @@
15
15
  'border-body-v': props.bordered === 'body-v',
16
16
  stripe: props.stripe,
17
17
  }"
18
- :style="virtual && { '--row-height': virtualScroll.rowHeight + 'px' }"
18
+ :style="
19
+ virtual && {
20
+ '--row-height': virtualScroll.rowHeight + 'px',
21
+ '--header-row-height': (props.headerRowHeight || props.rowHeight) + 'px',
22
+ }
23
+ "
19
24
  @scroll="onTableScroll"
20
25
  @wheel="onTableWheel"
21
26
  >
22
- <!-- 横向滚动时固定列的阴影,TODO: 覆盖一层在整个表上,使用linear-gradient 绘制阴影-->
23
- <!-- <div
24
- :class="showFixedLeftShadow && 'stk-table-fixed-left-col-box-shadow'"
25
- :style="{ width: fixedLeftColWidth + 'px' }"
26
- ></div> -->
27
27
  <!-- 这个元素用于虚拟滚动时,撑开父容器的高度 (已弃用,因为滚动条拖动过快,下方tr为加载出来时,会导致表头sticky闪动)
28
28
  <div
29
29
  v-if="virtual"
@@ -67,8 +67,7 @@
67
67
  col.dataIndex === sortCol && sortOrderIndex !== 0 && 'sorter-' + sortSwitchOrder[sortOrderIndex],
68
68
  showHeaderOverflow ? 'text-overflow' : '',
69
69
  col.headerClassName,
70
- col.fixed ? 'fixed-cell' : '',
71
- col.fixed ? 'fixed-cell--' + col.fixed : '',
70
+ ...getFixedColClass(col),
72
71
  ]"
73
72
  @click="
74
73
  e => {
@@ -83,7 +82,7 @@
83
82
  <div class="table-header-cell-wrapper">
84
83
  <component :is="col.customHeaderCell" v-if="col.customHeaderCell" :col="col" />
85
84
  <template v-else>
86
- <slot name="tableHeader" :column="col">
85
+ <slot name="tableHeader" :col="col">
87
86
  <span class="table-header-title">{{ col.title }}</span>
88
87
  </slot>
89
88
  </template>
@@ -91,14 +90,12 @@
91
90
  <!-- 排序图图标 -->
92
91
  <span v-if="col.sorter" class="table-header-sorter">
93
92
  <svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 16 16">
94
- <g id="sort-btn">
95
- <polygon id="arrow-up" fill="#757699" points="8 2 4.8 6 11.2 6"></polygon>
96
- <polygon
97
- id="arrow-down"
98
- transform="translate(8, 12) rotate(-180) translate(-8, -12) "
99
- points="8 10 4.8 14 11.2 14"
100
- ></polygon>
101
- </g>
93
+ <polygon class="arrow-up" fill="#757699" points="8 2 4.8 6 11.2 6"></polygon>
94
+ <polygon
95
+ class="arrow-down"
96
+ transform="translate(8, 12) rotate(-180) translate(-8, -12) "
97
+ points="8 10 4.8 14 11.2 14"
98
+ ></polygon>
102
99
  </svg>
103
100
  </span>
104
101
  <!-- 列宽拖动handler -->
@@ -164,12 +161,7 @@
164
161
  v-for="col in virtualX_columnPart"
165
162
  :key="col.dataIndex"
166
163
  :data-index="col.dataIndex"
167
- :class="[
168
- col.className,
169
- showOverflow ? 'text-overflow' : '',
170
- col.fixed ? 'fixed-cell' : '',
171
- col.fixed ? 'fixed-cell--' + col.fixed : '',
172
- ]"
164
+ :class="[col.className, showOverflow ? 'text-overflow' : '', ...getFixedColClass(col)]"
173
165
  :style="getCellStyle(2, col)"
174
166
  @click="e => onCellClick(e, row, col)"
175
167
  >
@@ -188,7 +180,7 @@
188
180
  </div>
189
181
  </template>
190
182
 
191
- <script setup lang="ts">
183
+ <script setup lang="tsx">
192
184
  /**
193
185
  * @author JA+
194
186
  * 不支持低版本浏览器非虚拟滚动表格的表头固定,列固定,因为会卡。
@@ -197,7 +189,8 @@
197
189
  * [] 计算的高亮颜色,挂在数据源上对象上,若多个表格使用同一个数据源对象会有问题。需要深拷贝。(解决方案:获取组件uid)
198
190
  * [] highlight-row 颜色不能恢复到active的颜色
199
191
  */
200
- import { CSSProperties, onMounted, ref, shallowRef, toRaw, watch } from 'vue';
192
+ import { CSSProperties, VNode, onMounted, ref, shallowRef, toRaw, watch } from 'vue';
193
+ import { Default_Row_Height } from './const';
201
194
  import { Order, SortOption, StkTableColumn, UniqKey } from './types/index';
202
195
  import { useAutoResize } from './useAutoResize';
203
196
  import { useColResize } from './useColResize';
@@ -230,14 +223,16 @@ const props = withDefaults(
230
223
  theme?: 'light' | 'dark';
231
224
  /** 行高 */
232
225
  rowHeight?: number;
226
+ /** 表头行高。default = rowHeight */
227
+ headerRowHeight?: number | null;
233
228
  /** 虚拟滚动 */
234
229
  virtual?: boolean;
235
230
  /** x轴虚拟滚动 */
236
231
  virtualX?: boolean;
237
232
  /** 表格列配置 */
238
- columns?: StkTableColumn<any>[];
233
+ columns?: StkTableColumn<DT>[];
239
234
  /** 表格数据源 */
240
- dataSource?: any[];
235
+ dataSource?: DT[];
241
236
  /** 行唯一键 */
242
237
  rowKey?: UniqKey;
243
238
  /** 列唯一键 */
@@ -285,6 +280,8 @@ const props = withDefaults(
285
280
  * 传入方法表示resize后的回调
286
281
  */
287
282
  autoResize?: boolean | (() => void);
283
+ /** 是否展示固定列阴影。默认不展示。 */
284
+ fixedColShadow?: boolean;
288
285
  }>(),
289
286
  {
290
287
  width: '',
@@ -294,7 +291,8 @@ const props = withDefaults(
294
291
  maxWidth: '',
295
292
  headless: false,
296
293
  theme: 'light',
297
- rowHeight: 28,
294
+ rowHeight: Default_Row_Height,
295
+ headerRowHeight: null,
298
296
  virtual: false,
299
297
  virtualX: false,
300
298
  columns: () => [],
@@ -314,39 +312,88 @@ const props = withDefaults(
314
312
  colMinWidth: 10,
315
313
  bordered: true,
316
314
  autoResize: true,
315
+ fixedColShadow: false,
317
316
  },
318
317
  );
319
318
 
320
319
  const emits = defineEmits<{
321
- /** 排序变更触发 */
320
+ /**
321
+ * 排序变更触发
322
+ * ```(col: StkTableColumn<DT>, order: Order, data: DT[])```
323
+ */
322
324
  (e: 'sort-change', col: StkTableColumn<DT>, order: Order, data: DT[]): void;
323
- /** 一行点击事件 */
325
+ /**
326
+ * 一行点击事件
327
+ * ```(ev: MouseEvent, row: DT)```
328
+ */
324
329
  (e: 'row-click', ev: MouseEvent, row: DT): void;
325
- /** 选中一行触发。ev返回null表示不是点击事件触发的 */
330
+ /**
331
+ * 选中一行触发。ev返回null表示不是点击事件触发的
332
+ * ```(ev: MouseEvent | null, row: DT)```
333
+ */
326
334
  (e: 'current-change', ev: MouseEvent | null, row: DT): void;
327
- /** 行双击事件 */
335
+ /**
336
+ * 行双击事件
337
+ * ```(ev: MouseEvent, row: DT)```
338
+ */
328
339
  (e: 'row-dblclick', ev: MouseEvent, row: DT): void;
329
- /** 表头右键事件 */
340
+ /**
341
+ * 表头右键事件
342
+ * ```(ev: MouseEvent)```
343
+ */
330
344
  (e: 'header-row-menu', ev: MouseEvent): void;
331
- /** 表体行右键点击事件 */
345
+ /**
346
+ * 表体行右键点击事件
347
+ * ```(ev: MouseEvent, row: DT)```
348
+ */
332
349
  (e: 'row-menu', ev: MouseEvent, row: DT): void;
333
- /** 单元格点击事件 */
350
+ /**
351
+ * 单元格点击事件
352
+ * ```(ev: MouseEvent, row: DT, col: StkTableColumn<DT>)```
353
+ */
334
354
  (e: 'cell-click', ev: MouseEvent, row: DT, col: StkTableColumn<DT>): void;
335
- /**表头单元格点击事件 */
355
+ /**
356
+ * 表头单元格点击事件
357
+ * ```(ev: MouseEvent, col: StkTableColumn<DT>)```
358
+ */
336
359
  (e: 'header-cell-click', ev: MouseEvent, col: StkTableColumn<DT>): void;
337
- /** 表格滚动事件 */
360
+ /**
361
+ * 表格滚动事件
362
+ * ```(ev: Event, data: { startIndex: number; endIndex: number })```
363
+ */
338
364
  (e: 'scroll', ev: Event, data: { startIndex: number; endIndex: number }): void;
339
- /** 表格横向滚动事件 */
365
+ /**
366
+ * 表格横向滚动事件
367
+ * ```(ev: Event)```
368
+ */
340
369
  (e: 'scroll-x', ev: Event): void;
341
- /** 表头列拖动事件 */
370
+ /**
371
+ * 表头列拖动事件
372
+ * ```(dragStartKey: string, targetColKey: string)```
373
+ */
342
374
  (e: 'col-order-change', dragStartKey: string, targetColKey: string): void;
343
- /** 表头列拖动开始 */
375
+ /**
376
+ * 表头列拖动开始
377
+ * ```(dragStartKey: string)```
378
+ */
344
379
  (e: 'th-drag-start', dragStartKey: string): void;
345
- /** 表头列拖动drop */
380
+ /**
381
+ * 表头列拖动drop
382
+ * ```(targetColKey: string)```
383
+ */
346
384
  (e: 'th-drop', targetColKey: string): void;
385
+ /** v-model:columns col resize 时更新宽度*/
347
386
  (e: 'update:columns', cols: StkTableColumn<DT>[]): void;
348
387
  }>();
349
388
 
389
+ // 仅支持vue3.3+
390
+ // const slots = defineSlots<{
391
+ // /** 表头插槽 */
392
+ // tableHeader(props: { col: StkTableColumn<DT> }): void;
393
+ // /** 空状态插槽 */
394
+ // empty(): void;
395
+ // }>();
396
+
350
397
  const tableContainer = ref<HTMLDivElement>();
351
398
  const colResizeIndicator = ref<HTMLDivElement>();
352
399
  /** 当前选中的一行*/
@@ -376,7 +423,17 @@ const tableHeaders = ref<StkTableColumn<DT>[][]>([]);
376
423
  /** 若有多级表头时,最后一行的tableHeaders.内容是 props.columns 的引用集合 */
377
424
  const tableHeaderLast = ref<StkTableColumn<DT>[]>([]);
378
425
 
379
- const dataSourceCopy = shallowRef([...props.dataSource]);
426
+ const dataSourceCopy = shallowRef<DT[]>([...props.dataSource]);
427
+
428
+ /** 固定列阴影 */
429
+ const fixedShadow = ref({
430
+ /** 是否展示左侧固定列阴影 */
431
+ showL: false,
432
+ /** 是否展示右侧固定列阴影 */
433
+ showR: false,
434
+ /** 保存需要出现阴影的列 */
435
+ cols: [] as StkTableColumn<DT>[],
436
+ });
380
437
 
381
438
  /**高亮帧间隔
382
439
  const highlightStepDuration = Highlight_Color_Change_Freq / 1000 + 's';*/
@@ -431,9 +488,11 @@ if (props.autoResize) {
431
488
 
432
489
  /** 键盘箭头滚动 */
433
490
  useKeyboardArrowScroll(tableContainer, {
491
+ props,
434
492
  scrollTo,
435
493
  virtualScroll,
436
494
  virtualScrollX,
495
+ tableHeaders,
437
496
  });
438
497
 
439
498
  watch(
@@ -453,7 +512,6 @@ watch(
453
512
  console.warn('invalid dataSource');
454
513
  return;
455
514
  }
456
- // dealColumns(val);
457
515
  let needInitVirtualScrollY = false;
458
516
  if (dataSourceCopy.value.length !== val.length) {
459
517
  needInitVirtualScrollY = true;
@@ -467,6 +525,7 @@ watch(
467
525
  const column = tableHeaderLast.value.find(it => it.dataIndex === sortCol.value);
468
526
  onColumnSort(column, false);
469
527
  }
528
+ updateFixedShadow();
470
529
  },
471
530
  {
472
531
  deep: false,
@@ -474,11 +533,11 @@ watch(
474
533
  );
475
534
  onMounted(() => {
476
535
  initVirtualScroll();
536
+ updateFixedShadow();
477
537
  });
478
538
 
479
539
  /**
480
540
  * 处理多级表头
481
- * FIXME: 仅支持到两级表头。不支持多级。
482
541
  */
483
542
  function dealColumns() {
484
543
  // reset
@@ -497,9 +556,10 @@ function dealColumns() {
497
556
  /**
498
557
  * @param arr
499
558
  * @param depth 深度
559
+ * @param parent 父节点引用,用于构建双向链表。
500
560
  * @param parentFixed 父节点固定列继承。
501
561
  */
502
- function flat(arr: StkTableColumn<any>[], depth = 0 /* , parentFixed: 'left' | 'right' | null = null */) {
562
+ function flat(arr: StkTableColumn<DT>[], parent: StkTableColumn<DT> | null, depth = 0 /* , parentFixed: 'left' | 'right' | null = null */) {
503
563
  if (!tableHeaders.value[depth]) {
504
564
  tableHeaders.value[depth] = [];
505
565
  }
@@ -510,11 +570,13 @@ function dealColumns() {
510
570
  // if (parentFixed) {
511
571
  // col.fixed = parentFixed;
512
572
  // }
573
+ // 构建指向父节点的引用
574
+ col.__PARENT__ = parent;
513
575
  /** 一列中的子节点数量 */
514
576
  let colChildrenLen = 1;
515
577
  if (col.children) {
516
578
  // DFS
517
- colChildrenLen = flat(col.children, depth + 1 /* , col.fixed */);
579
+ colChildrenLen = flat(col.children, col, depth + 1 /* , col.fixed */);
518
580
  } else {
519
581
  tempHeaderLast.push(col); // 没有children的列作为colgroup
520
582
  }
@@ -532,15 +594,58 @@ function dealColumns() {
532
594
  });
533
595
  return allChildrenLen;
534
596
  }
535
- flat(copyColumn);
597
+
598
+ flat(copyColumn, null);
536
599
 
537
600
  tableHeaderLast.value = tempHeaderLast;
601
+ dealFixedColShadow();
602
+ }
603
+
604
+ /** 处理固定列阴影 */
605
+ function dealFixedColShadow() {
606
+ if (!props.fixedColShadow) return;
607
+ fixedShadow.value.cols = [];
608
+ const lastLeftCol = tableHeaderLast.value.findLast(it => it.fixed === 'left');
609
+ const lastRightCol = tableHeaderLast.value.find(it => it.fixed === 'right');
610
+ // 处理多级表头列阴影
611
+ let node: any = { __PARENT__: lastLeftCol };
612
+ while ((node = node.__PARENT__)) {
613
+ if (node.fixed) {
614
+ fixedShadow.value.cols.push(node);
615
+ }
616
+ }
617
+ node = { __PARENT__: lastRightCol };
618
+ while ((node = node.__PARENT__)) {
619
+ if (node.fixed) {
620
+ fixedShadow.value.cols.push(node);
621
+ }
622
+ }
623
+ }
624
+
625
+ /** 固定列class */
626
+ function getFixedColClass(col: StkTableColumn<DT>): string[] {
627
+ const { showR, showL, cols } = fixedShadow.value;
628
+ const classArr = [
629
+ col.fixed ? 'fixed-cell' : '',
630
+ col.fixed ? 'fixed-cell--' + col.fixed : '',
631
+ props.fixedColShadow && col.fixed && ((showL && col.fixed === 'left') || (showR && col.fixed === 'right')) && cols.includes(col)
632
+ ? 'fixed-cell--shadow'
633
+ : '',
634
+ ];
635
+ return classArr;
636
+ }
637
+
638
+ function updateFixedShadow() {
639
+ if (!props.fixedColShadow) return;
640
+ const { clientWidth, scrollWidth, scrollLeft } = tableContainer.value as HTMLDivElement;
641
+ fixedShadow.value.showL = Boolean(scrollLeft);
642
+ fixedShadow.value.showR = Math.abs(scrollWidth - scrollLeft - clientWidth) > 0.5;
538
643
  }
539
644
 
540
645
  /**
541
646
  * 行唯一值生成
542
647
  */
543
- function rowKeyGen(row: any) {
648
+ function rowKeyGen(row: DT) {
544
649
  let key = rowKeyGenStore.get(row);
545
650
  if (!key) {
546
651
  key = typeof props.rowKey === 'function' ? props.rowKey(row) : row[props.rowKey];
@@ -678,10 +783,12 @@ function onTableWheel(e: MouseEvent) {
678
783
  function onTableScroll(e: Event) {
679
784
  if (!e?.target) return;
680
785
 
681
- // 此处可优化,因为访问e.target.scrollXX消耗性能
682
786
  const { scrollTop, scrollLeft } = e.target as HTMLElement;
683
- const isYScroll = scrollTop !== virtualScroll.value.scrollTop;
684
- const isXScroll = scrollLeft !== virtualScrollX.value.scrollLeft;
787
+ const { scrollTop: vScrollTop, startIndex, endIndex } = virtualScroll.value;
788
+ const { scrollLeft: vScrollLeft } = virtualScrollX.value;
789
+ const isYScroll = scrollTop !== vScrollTop;
790
+ const isXScroll = scrollLeft !== vScrollLeft;
791
+
685
792
  // 纵向滚动有变化
686
793
  if (isYScroll) {
687
794
  virtualScroll.value.scrollTop = scrollTop;
@@ -693,14 +800,12 @@ function onTableScroll(e: Event) {
693
800
  // 横向滚动有变化
694
801
  if (isXScroll) {
695
802
  virtualScrollX.value.scrollLeft = scrollLeft;
803
+ updateFixedShadow();
696
804
  }
697
805
  if (virtualX_on.value) {
698
806
  updateVirtualScrollX(scrollLeft);
699
807
  }
700
- const data = {
701
- startIndex: virtualScroll.value.startIndex,
702
- endIndex: virtualScroll.value.endIndex,
703
- };
808
+ const data = { startIndex, endIndex };
704
809
  if (isYScroll) {
705
810
  emits('scroll', e, data);
706
811
  }
@@ -775,16 +880,27 @@ function getTableData() {
775
880
  }
776
881
 
777
882
  defineExpose({
883
+ /** 初始化横向纵向虚拟滚动 */
778
884
  initVirtualScroll,
885
+ /** 初始化横向虚拟滚动 */
779
886
  initVirtualScrollX,
887
+ /** 初始化纵向虚拟滚动 */
780
888
  initVirtualScrollY,
889
+ /** 设置当前选中行 */
781
890
  setCurrentRow,
891
+ /** 设置高亮渐暗单元格 */
782
892
  setHighlightDimCell,
893
+ /** 设置高亮渐暗行 */
783
894
  setHighlightDimRow,
895
+ /** 表格排序列dataIndex */
784
896
  sortCol,
897
+ /** 设置排序 */
785
898
  setSorter,
899
+ /** 重置排序 */
786
900
  resetSorter,
901
+ /** 滚动至 */
787
902
  scrollTo,
903
+ /** 获取表格数据 */
788
904
  getTableData,
789
905
  });
790
906
  </script>
@@ -2,6 +2,7 @@ export const Default_Col_Width = '100';
2
2
 
3
3
  export const Default_Table_Height = 100;
4
4
  export const Default_Table_Width = 200;
5
+ export const Default_Row_Height = 28;
5
6
 
6
7
  /** 高亮背景色 */
7
8
  export const Highlight_Color = {