stk-table-vue 0.4.1 → 0.4.3

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/package.json CHANGED
@@ -1,65 +1,65 @@
1
- {
2
- "name": "stk-table-vue",
3
- "version": "0.4.1",
4
- "description": "Simple realtime virtual table for vue3 and vue2.7",
5
- "main": "./lib/stk-table-vue.js",
6
- "types": "./lib/src/StkTable/index.d.ts",
7
- "packageManager": "pnpm@8.14.3",
8
- "directories": {
9
- "test": "test"
10
- },
11
- "type": "module",
12
- "scripts": {
13
- "dev": "vite",
14
- "build": "vite build",
15
- "test": "vitest"
16
- },
17
- "keywords": [
18
- "virtual table",
19
- "vue",
20
- "vue2",
21
- "vue3",
22
- "highlight",
23
- "sticky",
24
- "virtual",
25
- "table",
26
- "list"
27
- ],
28
- "files": [
29
- "lib",
30
- "src"
31
- ],
32
- "author": "japlus",
33
- "repository": {
34
- "type": "git",
35
- "url": "https://github.com/ja-plus/stk-table-vue"
36
- },
37
- "license": "MIT",
38
- "devDependencies": {
39
- "@types/d3-interpolate": "^3.0.4",
40
- "@types/node": "^20.11.14",
41
- "@typescript-eslint/eslint-plugin": "^6.14.0",
42
- "@typescript-eslint/parser": "^6.14.0",
43
- "@vitejs/plugin-vue": "^5.0.4",
44
- "@vue/test-utils": "2.4.4",
45
- "eslint": "^8.55.0",
46
- "eslint-config-prettier": "^9.1.0",
47
- "eslint-plugin-html": "^7.1.0",
48
- "eslint-plugin-prettier": "^5.0.1",
49
- "eslint-plugin-vue": "^9.19.2",
50
- "happy-dom": "^12.10.3",
51
- "less": "^4.2.0",
52
- "postcss-discard-comments": "^6.0.1",
53
- "postcss-preset-env": "^9.3.0",
54
- "prettier": "^3.1.1",
55
- "typescript": "^5.3.3",
56
- "vite": "^5.2.0",
57
- "vite-plugin-dts": "^3.7.3",
58
- "vitest": "^1.1.0",
59
- "vue": "^3.4.21",
60
- "vue-eslint-parser": "^9.3.2"
61
- },
62
- "dependencies": {
63
- "d3-interpolate": "^3.0.1"
64
- }
1
+ {
2
+ "name": "stk-table-vue",
3
+ "version": "0.4.3",
4
+ "description": "Simple realtime virtual table for vue3 and vue2.7",
5
+ "main": "./lib/stk-table-vue.js",
6
+ "types": "./lib/src/StkTable/index.d.ts",
7
+ "packageManager": "pnpm@8.14.3",
8
+ "directories": {
9
+ "test": "test"
10
+ },
11
+ "type": "module",
12
+ "scripts": {
13
+ "dev": "vite",
14
+ "build": "vite build",
15
+ "test": "vitest"
16
+ },
17
+ "keywords": [
18
+ "virtual table",
19
+ "vue",
20
+ "vue2",
21
+ "vue3",
22
+ "highlight",
23
+ "sticky",
24
+ "virtual",
25
+ "table",
26
+ "list"
27
+ ],
28
+ "files": [
29
+ "lib",
30
+ "src"
31
+ ],
32
+ "author": "japlus",
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "https://github.com/ja-plus/stk-table-vue"
36
+ },
37
+ "license": "MIT",
38
+ "devDependencies": {
39
+ "@types/d3-interpolate": "^3.0.4",
40
+ "@types/node": "^20.12.10",
41
+ "@typescript-eslint/eslint-plugin": "^7.7.0",
42
+ "@typescript-eslint/parser": "^7.7.0",
43
+ "@vitejs/plugin-vue": "^5.0.4",
44
+ "@vue/test-utils": "2.4.4",
45
+ "eslint": "^8.57.0",
46
+ "eslint-config-prettier": "^9.1.0",
47
+ "eslint-plugin-html": "^8.1.0",
48
+ "eslint-plugin-prettier": "^5.1.3",
49
+ "eslint-plugin-vue": "^9.25.0",
50
+ "happy-dom": "^12.10.3",
51
+ "less": "^4.2.0",
52
+ "postcss-discard-comments": "^6.0.2",
53
+ "postcss-preset-env": "^9.5.11",
54
+ "prettier": "^3.2.5",
55
+ "typescript": "^5.4.5",
56
+ "vite": "^5.2.11",
57
+ "vite-plugin-dts": "^3.9.1",
58
+ "vitest": "^1.6.0",
59
+ "vue": "^3.4.26",
60
+ "vue-eslint-parser": "^9.4.2"
61
+ },
62
+ "dependencies": {
63
+ "d3-interpolate": "^3.0.1"
64
+ }
65
65
  }
@@ -15,6 +15,8 @@
15
15
  'border-body-v': props.bordered === 'body-v',
16
16
  stripe: props.stripe,
17
17
  'cell-hover': props.cellHover,
18
+ 'row-hover': props.rowHover,
19
+ 'row-active': props.rowActive,
18
20
  'text-overflow': props.showOverflow,
19
21
  'header-text-overflow': props.showHeaderOverflow,
20
22
  'fixed-relative-mode': isRelativeMode,
@@ -45,7 +47,7 @@
45
47
  }"
46
48
  >
47
49
  <!-- transform: virtualX_on ? `translateX(${virtualScrollX.offsetLeft}px)` : null, 用transform控制虚拟滚动左边距,sticky会有问题 -->
48
- <thead v-if="!headless">
50
+ <thead v-if="!headless" ref="theadRef">
49
51
  <tr v-for="(row, rowIndex) in tableHeaders" :key="rowIndex" @contextmenu="e => onHeaderMenu(e)">
50
52
  <!-- 这个th用于横向虚拟滚动表格左边距,width、maxWidth 用于兼容低版本浏览器 -->
51
53
  <th
@@ -83,7 +85,7 @@
83
85
  @dragover="onThDragOver"
84
86
  >
85
87
  <div class="table-header-cell-wrapper">
86
- <component :is="col.customHeaderCell" v-if="col.customHeaderCell" :col="col" />
88
+ <component :is="col.customHeaderCell" v-if="col.customHeaderCell" :col="col" :colIndex="colIndex" :rowIndex="rowIndex" />
87
89
  <template v-else-if="col.type === 'seq'">
88
90
  <span class="table-header-title">{{ col.title }}</span>
89
91
  </template>
@@ -142,8 +144,8 @@
142
144
  <!--这个td用于配合虚拟滚动的th对应,防止列错位-->
143
145
  <td v-if="virtualX_on && fixedMode && headless" class="virtual-x-left"></td>
144
146
  <template v-if="fixedMode && headless">
145
- <td v-for="col in virtualX_columnPart" :key="col.dataIndex" :style="cellStyleMap[TagType.TD].get(colKeyGen(col))"></td
146
- ></template>
147
+ <td v-for="col in virtualX_columnPart" :key="col.dataIndex" :style="cellStyleMap[TagType.TD].get(colKeyGen(col))"></td>
148
+ </template>
147
149
  </tr>
148
150
  </tbody>
149
151
  <tbody class="stk-tbody-main">
@@ -182,14 +184,14 @@
182
184
  :row="row"
183
185
  :rowIndex="rowIndex"
184
186
  :colIndex="colIndex"
185
- :cellValue="row[col.dataIndex]"
187
+ :cellValue="row?.[col.dataIndex]"
186
188
  />
187
- <div v-else class="table-cell-wrapper" :title="!col.type ? row[col.dataIndex] : ''">
189
+ <div v-else class="table-cell-wrapper" :title="!col.type ? row?.[col.dataIndex] : ''">
188
190
  <template v-if="col.type === 'seq'">
189
191
  {{ (props.seqConfig.startIndex || 0) + rowIndex + 1 }}
190
192
  </template>
191
193
  <template v-else>
192
- {{ row[col.dataIndex] ?? getEmptyCellText(col, row) }}
194
+ {{ row?.[col.dataIndex] ?? getEmptyCellText(col, row) }}
193
195
  </template>
194
196
  </div>
195
197
  </td>
@@ -208,11 +210,8 @@
208
210
  <script setup lang="ts">
209
211
  /**
210
212
  * @author JA+
211
- * 不支持低版本浏览器非虚拟滚动表格的表头固定,列固定,因为会卡。
212
213
  * TODO:存在的问题:
213
214
  * [] column.dataIndex 作为唯一键,不能重复
214
- * [] 计算的高亮颜色,挂在数据源上对象上,若多个表格使用同一个数据源对象会有问题。需要深拷贝。(解决方案:获取组件uid)
215
- * [] highlight-row 颜色不能恢复到active的颜色
216
215
  */
217
216
  import { CSSProperties, computed, nextTick, onMounted, ref, shallowRef, toRaw, watch } from 'vue';
218
217
  import { DEFAULT_ROW_HEIGHT, IS_LEGACY_MODE } from './const';
@@ -229,7 +228,7 @@ import { useVirtualScroll } from './useVirtualScroll';
229
228
  import { createStkTableId, getCalculatedColWidth, getColWidth, howDeepTheHeader, tableSort, transformWidthToStr } from './utils/index';
230
229
 
231
230
  /** Generic stands for DataType */
232
- type DT = any;
231
+ type DT = Record<string | number, any>;
233
232
  /** 自己生成实例id */
234
233
  const stkTableId = createStkTableId();
235
234
  /**
@@ -244,7 +243,7 @@ const props = withDefaults(
244
243
  maxWidth?: string;
245
244
  /** 斑马线条纹 */
246
245
  stripe?: boolean;
247
- /** 是否使用 table-layout:fixed */
246
+ /** 是否使用 table-layout:fixed(低版本浏览器需要设置table) */
248
247
  fixedMode?: boolean;
249
248
  /** 是否隐藏表头 */
250
249
  headless?: boolean;
@@ -252,6 +251,12 @@ const props = withDefaults(
252
251
  theme?: 'light' | 'dark';
253
252
  /** 行高 */
254
253
  rowHeight?: number;
254
+ /** 是否高亮鼠标悬浮的行 */
255
+ rowHover?: boolean;
256
+ /** 是否高亮选中的行 */
257
+ rowActive?: boolean;
258
+ /** 当前行再次点击否可以取消 */
259
+ rowCurrentRevokable?: boolean;
255
260
  /** 表头行高。default = rowHeight */
256
261
  headerRowHeight?: number | null;
257
262
  /** 虚拟滚动 */
@@ -262,7 +267,7 @@ const props = withDefaults(
262
267
  columns?: StkTableColumn<DT>[];
263
268
  /** 表格数据源 */
264
269
  dataSource?: DT[];
265
- /** 行唯一键 */
270
+ /** 行唯一键 (行唯一值不能为undefined) */
266
271
  rowKey?: UniqKeyProp;
267
272
  /** 列唯一键 */
268
273
  colKey?: UniqKeyProp;
@@ -278,7 +283,7 @@ const props = withDefaults(
278
283
  showHeaderOverflow?: boolean;
279
284
  /** 表体溢出是否展示... */
280
285
  showOverflow?: boolean;
281
- /** 是否增加行hover class */
286
+ /** 是否增加行hover class $*$ rename*/
282
287
  showTrHoverClass?: boolean;
283
288
  /** 是否高亮鼠标悬浮的单元格 */
284
289
  cellHover?: boolean;
@@ -343,6 +348,9 @@ const props = withDefaults(
343
348
  headless: false,
344
349
  theme: 'light',
345
350
  rowHeight: DEFAULT_ROW_HEIGHT,
351
+ rowHover: true,
352
+ rowActive: true,
353
+ rowCurrentRevokable: true,
346
354
  headerRowHeight: null,
347
355
  virtual: false,
348
356
  virtualX: false,
@@ -390,9 +398,9 @@ const emits = defineEmits<{
390
398
  (e: 'row-click', ev: MouseEvent, row: DT): void;
391
399
  /**
392
400
  * 选中一行触发。ev返回null表示不是点击事件触发的
393
- * ```(ev: MouseEvent | null, row: DT, data: { select: boolean })```
401
+ * ```(ev: MouseEvent | null, row: DT | undefined, data: { select: boolean })```
394
402
  */
395
- (e: 'current-change', ev: MouseEvent | null, row: DT, data: { select: boolean }): void;
403
+ (e: 'current-change', ev: MouseEvent | null, row: DT | undefined, data: { select: boolean }): void;
396
404
  /**
397
405
  * 行双击事件
398
406
  * ```(ev: MouseEvent, row: DT)```
@@ -471,27 +479,31 @@ const emits = defineEmits<{
471
479
  // }>();
472
480
 
473
481
  const tableContainerRef = ref<HTMLDivElement>();
482
+ const theadRef = ref<HTMLElement>();
474
483
  const colResizeIndicatorRef = ref<HTMLDivElement>();
475
484
 
476
485
  /** 是否使用 relative 固定头和列 */
477
486
  const isRelativeMode = ref(IS_LEGACY_MODE ? true : props.cellFixedMode === 'relative');
478
487
 
479
- /** 当前选中的一行*/
480
- const currentRow = ref<DT | null>(null);
488
+ /**
489
+ * 当前选中的一行
490
+ * - shallowRef: 使 currentRow.value === row 地址相同。防止rowKeyGen 的WeakMap key不一致。
491
+ */
492
+ const currentRow = shallowRef<DT>();
481
493
  /**
482
494
  * 保存当前选中行的key<br>
483
495
  * 原因:vue3 不用ref包dataSource时,row为原始对象,与currentItem(Ref)相比会不相等。
484
496
  */
485
497
  const currentRowKey = ref<any>(null);
486
498
  /** 当前hover行 */
487
- let currentHoverRow: DT = null;
499
+ let currentHoverRow: DT | null = null;
488
500
  /** 当前hover的行的key */
489
501
  const currentHoverRowKey = ref(null);
490
502
  /** 当前hover的列的key */
491
503
  // const currentColHoverKey = ref(null);
492
504
 
493
505
  /** 排序的列dataIndex*/
494
- let sortCol = ref<string | null>();
506
+ let sortCol = ref<keyof DT>();
495
507
  let sortOrderIndex = ref(0);
496
508
 
497
509
  /** 排序切换顺序 */
@@ -566,7 +578,7 @@ const {
566
578
  initVirtualScrollX,
567
579
  updateVirtualScrollY,
568
580
  updateVirtualScrollX,
569
- } = useVirtualScroll({ tableContainerRef, props, dataSourceCopy, tableHeaderLast, tableHeaders });
581
+ } = useVirtualScroll({ tableContainerRef, theadRef, props, dataSourceCopy, tableHeaderLast, tableHeaders });
570
582
 
571
583
  /** 获取固定列的位置 */
572
584
  const getFixedColPosition = useGetFixedColPosition({ colKeyGen, tableHeaders });
@@ -640,21 +652,23 @@ watch(
640
652
  console.warn('invalid dataSource');
641
653
  return;
642
654
  }
655
+ /** 是否需要更新ScrollY,这里由于watch newValue与oldValue 的长度一样,因此需要这样使用 */
643
656
  let needInitVirtualScrollY = false;
644
657
  if (dataSourceCopy.value.length !== val.length) {
645
658
  needInitVirtualScrollY = true;
646
659
  }
647
660
  dataSourceCopy.value = [...val];
648
661
  // 数据长度没变则不计算虚拟滚动
649
- if (needInitVirtualScrollY) initVirtualScrollY();
662
+ if (needInitVirtualScrollY) {
663
+ // 表格渲染后再执行。initVirtualScrollY 中有获取dom的操作。
664
+ nextTick(() => initVirtualScrollY());
665
+ }
650
666
 
651
667
  if (sortCol.value) {
652
668
  // 排序
653
669
  const column = tableHeaderLast.value.find(it => it.dataIndex === sortCol.value);
654
670
  onColumnSort(column, false);
655
671
  }
656
- // 是否需要
657
- // updateFixedShadow();
658
672
  },
659
673
  {
660
674
  deep: false,
@@ -771,11 +785,16 @@ function dealColumns() {
771
785
  /**
772
786
  * 行唯一值生成
773
787
  */
774
- function rowKeyGen(row: DT) {
775
- if (!row) return;
788
+ function rowKeyGen(row: DT | null | undefined) {
789
+ if (!row) return row;
776
790
  let key = rowKeyGenStore.get(row);
777
791
  if (!key) {
778
792
  key = typeof props.rowKey === 'function' ? props.rowKey(row) : row[props.rowKey];
793
+
794
+ if (key === void 0) {
795
+ // key为undefined时,不应该高亮行。因此重新生成key
796
+ key = Math.random().toString();
797
+ }
779
798
  rowKeyGenStore.set(row, key);
780
799
  }
781
800
  return key;
@@ -866,10 +885,15 @@ function onColumnSort(col?: StkTableColumn<DT>, click = true, options: { force?:
866
885
 
867
886
  function onRowClick(e: MouseEvent, row: DT) {
868
887
  emits('row-click', e, row);
869
- // 选中同一行,取消当前选中行。
870
- if (props.rowKey ? currentRowKey.value === rowKeyGen(row) : currentRow.value === row) {
871
- currentRow.value = null;
872
- currentRowKey.value = null;
888
+ const isCurrentRow = props.rowKey ? currentRowKey.value === rowKeyGen(row) : currentRow.value === row;
889
+ if (isCurrentRow) {
890
+ if (!props.rowCurrentRevokable) {
891
+ // 不可取消
892
+ return;
893
+ }
894
+ // 点击同一行,取消当前选中行。
895
+ currentRow.value = void 0;
896
+ currentRowKey.value = void 0;
873
897
  emits('current-change', e, row, { select: false });
874
898
  } else {
875
899
  currentRow.value = row;
@@ -924,7 +948,6 @@ function onCellMouseOver(e: MouseEvent, row: DT, col: StkTableColumn<DT>) {
924
948
  * @param e
925
949
  */
926
950
  function onTableWheel(e: WheelEvent) {
927
- e.preventDefault();
928
951
  if (isColResizing.value) {
929
952
  // 正在调整列宽时,不允许用户滚动
930
953
  e.stopPropagation();
@@ -933,9 +956,30 @@ function onTableWheel(e: WheelEvent) {
933
956
  // #region ---- 控制滚动,防止出现白屏--
934
957
  const dom = tableContainerRef.value;
935
958
  if (!dom) return;
959
+ const { containerHeight, scrollTop, scrollHeight, rowHeight } = virtualScroll.value;
960
+ const { containerWidth, scrollLeft, scrollWidth } = virtualScrollX.value;
961
+ /** 是否滚动在下面 */
962
+ const isScrollBottom = scrollHeight - containerHeight - scrollTop < rowHeight;
963
+ /** 是否滚动在右侧 */
964
+ const isScrollRight = scrollWidth - containerWidth - scrollLeft < 100;
936
965
  const { deltaY, deltaX } = e;
937
- if (deltaY) dom.scrollTop += deltaY;
938
- if (deltaX) dom.scrollLeft += deltaX;
966
+
967
+ /**
968
+ * 只有虚拟滚动时,才要用 wheel 代理scroll,防止滚动过快导致的白屏。
969
+ * 滚动条在边界情况时,not preventDefault 。因为会阻塞父级滚动条滚动。
970
+ */
971
+ if (virtual_on && deltaY) {
972
+ if ((deltaY > 0 && !isScrollBottom) || (deltaY < 0 && scrollTop > 0)) {
973
+ e.preventDefault();
974
+ }
975
+ dom.scrollTop += deltaY;
976
+ }
977
+ if (virtualX_on && deltaX) {
978
+ if ((deltaX > 0 && !isScrollRight) || (deltaX < 0 && scrollLeft > 0)) {
979
+ e.preventDefault();
980
+ }
981
+ dom.scrollLeft += deltaX;
982
+ }
939
983
  //#endregion
940
984
  }
941
985
 
@@ -1024,7 +1068,7 @@ function setSorter(dataIndex: string, order: Order, option: { sortOption?: SortO
1024
1068
 
1025
1069
  /** 重置排序 */
1026
1070
  function resetSorter() {
1027
- sortCol.value = null;
1071
+ sortCol.value = void 0;
1028
1072
  sortOrderIndex.value = 0;
1029
1073
  dataSourceCopy.value = [...props.dataSource];
1030
1074
  }
@@ -1046,7 +1090,7 @@ function getTableData() {
1046
1090
  }
1047
1091
 
1048
1092
  /** 获取当前排序列的信息 */
1049
- function getSortColumns(): SortState<DT>[] {
1093
+ function getSortColumns(): Partial<SortState<DT>>[] {
1050
1094
  const sortOrder = sortSwitchOrder[sortOrderIndex.value];
1051
1095
  if (!sortOrder) return [];
1052
1096
  return [{ dataIndex: sortCol.value, order: sortOrder }];
@@ -45,7 +45,13 @@
45
45
  display: flex;
46
46
  flex-direction: column;
47
47
  box-sizing: border-box;
48
- /* border-left: 此方案用于减少cell 中border-left 的css选择。同时利于多级表头border-left问题。利于横向滚动border-left*/
48
+ /**
49
+ * border-left: 此方案用于减少cell 中border-left 的css选择。同时利于多级表头border-left问题。利于横向滚动border-left
50
+ * - box-shadow inset 方案不生效,且占用属性。
51
+ * - outline 方案绘制在图形外
52
+ * - 绝对定位元素。需要根据滚动条位置动态计算。不合适。
53
+ * - sticky 定位方案需要占用位置。高度为0。
54
+ */
49
55
  border-left: 1px solid var(--border-color);
50
56
  /* 下面border用于表格内容不满高度时,绘制表格边界线 */
51
57
  background-image: var(--bg-border-top), var(--bg-border-right), var(--bg-border-bottom);
@@ -135,6 +141,15 @@
135
141
  }
136
142
  }
137
143
 
144
+ &.row-hover tbody tr:hover {
145
+ background-color: var(--tr-hover-bgc);
146
+ }
147
+
148
+
149
+ &.row-active tbody tr.active {
150
+ background-color: var(--tr-active-bgc);
151
+ }
152
+
138
153
  /* 单元格悬浮 */
139
154
  &.cell-hover tbody td:hover {
140
155
  box-shadow: inset 0 0 0 2px var(--td-hover-color);
@@ -252,29 +267,18 @@
252
267
 
253
268
  }
254
269
 
255
- thead {
256
- tr {
257
- background-color: var(--th-bgc);
258
- height: var(--header-row-height);
259
- }
270
+ thead tr {
271
+ background-color: var(--th-bgc);
272
+ height: var(--header-row-height);
260
273
  }
261
274
 
262
- /* stk-table-main 这层为了增加选择器优先级,防止被斑马纹颜色覆盖*/
263
- .stk-table-main tbody tr {
275
+
276
+ tbody tr {
264
277
  background-color: var(--td-bgc);
265
278
  height: var(--row-height);
266
- /** 一行分层,有利于高亮行重绘
267
- transform: translateZ(0);*/
268
-
269
- &:hover {
270
- background-color: var(--tr-hover-bgc);
271
- }
272
-
273
- &.active {
274
- background-color: var(--tr-active-bgc);
275
- }
276
279
  }
277
280
 
281
+
278
282
  .virtual-x-left,
279
283
  .virtual-x-right {
280
284
  padding: 0;
@@ -5,16 +5,32 @@ export type Order = null | 'asc' | 'desc';
5
5
 
6
6
  type Sorter<T> = boolean | ((data: T[], option: { order: Order; column: any }) => T[]);
7
7
 
8
- export type CustomCellFunc<T extends Record<string, any>> = (props: {
8
+ export type CustomCellProps<T extends Record<string, any>> = {
9
9
  row: T;
10
10
  col: StkTableColumn<T>;
11
11
  /** row[col.dataIndex] 的值 */
12
12
  cellValue: any;
13
13
  rowIndex: number;
14
14
  colIndex: number;
15
- }) => VNode;
15
+ };
16
+
17
+ /**
18
+ * $*$自定义单元格渲染函数
19
+ * @deprecated
20
+ */
21
+ export type CustomCellFunc<T extends Record<string, any>> = (props: CustomCellProps<T>) => VNode;
22
+
23
+ export type CustomHeaderCellProps<T extends Record<string, any>> = {
24
+ col: StkTableColumn<T>;
25
+ rowIndex: number;
26
+ colIndex: number;
27
+ };
16
28
 
17
- export type CustomHeaderCellFunc<T extends Record<string, any>> = (props: { col: StkTableColumn<T> }) => VNode;
29
+ /**
30
+ * $*$自定义表头渲染函数
31
+ * @deprecated
32
+ */
33
+ export type CustomHeaderCellFunc<T extends Record<string, any>> = (props: CustomHeaderCellProps<T>) => VNode;
18
34
 
19
35
  /** 表格列配置 */
20
36
  export type StkTableColumn<T extends Record<string, any>> = {
@@ -55,17 +71,22 @@ export type StkTableColumn<T extends Record<string, any>> = {
55
71
  * 自定义 td 渲染内容。
56
72
  *
57
73
  * 组件prop入参:
58
- * - props.row 一行的记录。
59
- * - props.col 列配置
74
+ * @param props.row 一行的记录。
75
+ * @param props.col 列配置
76
+ * @param props.cellValue row[col.dataIndex] 的值
77
+ * @param props.rowIndex 行索引
78
+ * @param props.colIndex 列索引
60
79
  */
61
- customCell?: Component | VNode | CustomCellFunc<T>;
80
+ customCell?: Component<CustomCellProps<T>> | string;
62
81
  /**
63
82
  * 自定义 th 渲染内容
64
83
  *
65
84
  * 组件prop入参:
66
- * - props.col 列配置
85
+ * @param props.col 列配置
86
+ * @param props.rowIndex 行索引
87
+ * @param props.colIndex 列索引
67
88
  */
68
- customHeaderCell?: Component | VNode | CustomHeaderCellFunc<T>;
89
+ customHeaderCell?: Component<CustomHeaderCellProps<T>> | string;
69
90
  /** 二级表头 */
70
91
  children?: StkTableColumn<T>[];
71
92
  /** 父节点引用 */
@@ -78,7 +99,7 @@ export type SortOption<T extends Record<string, any>> = Pick<StkTableColumn<T>,
78
99
 
79
100
  /** 排序状态 */
80
101
  export type SortState<T> = {
81
- dataIndex: T;
102
+ dataIndex: keyof T;
82
103
  order: null | 'asc' | 'desc';
83
104
  sortType?: 'number' | 'string';
84
105
  };
@@ -104,7 +125,7 @@ export type SortConfig<T extends Record<string, any>> = {
104
125
  };
105
126
  /**
106
127
  * string排序是否使用 String.prototype.localCompare
107
- * 默认true (&$&应该false)
128
+ * 默认true ($*$应该false)
108
129
  */
109
130
  stringLocaleCompare?: boolean;
110
131
  };
@@ -76,17 +76,17 @@ export function useFixedCol<DT extends Record<string, any>>({
76
76
  if (!props.fixedColShadow) return;
77
77
  const fixedColsTemp: StkTableColumn<DT>[] = [];
78
78
  const fixedShadowColsTemp: (StkTableColumn<DT> | null)[] = [];
79
- let clientWidth, scrollWidth, scrollLeft;
79
+ let clientWidth, /* scrollWidth, */ scrollLeft;
80
80
 
81
81
  if (virtualScrollX?.value) {
82
- const { containerWidth: cw, scrollWidth: sw, scrollLeft: sl } = virtualScrollX.value;
82
+ const { containerWidth: cw, /* scrollWidth: sw, */ scrollLeft: sl } = virtualScrollX.value;
83
83
  clientWidth = cw;
84
- scrollWidth = sw;
84
+ // scrollWidth = sw;
85
85
  scrollLeft = sl;
86
86
  } else {
87
- const { clientWidth: cw, scrollWidth: sw, scrollLeft: sl } = tableContainerRef.value as HTMLDivElement;
87
+ const { clientWidth: cw, /* scrollWidth: sw, */ scrollLeft: sl } = tableContainerRef.value as HTMLDivElement;
88
88
  clientWidth = cw;
89
- scrollWidth = sw;
89
+ // scrollWidth = sw;
90
90
  scrollLeft = sl;
91
91
  }
92
92