stk-table-vue 0.6.2 → 0.6.4

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,71 @@
1
1
  {
2
- "name": "stk-table-vue",
3
- "version": "0.6.2",
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.1.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.4.10",
57
- "vite-plugin-dts": "^4.3.0",
58
- "vitest": "^2.1.3",
59
- "vue": "^3.5.12",
60
- "vue-eslint-parser": "^9.4.2"
61
- },
62
- "dependencies": {
63
- "d3-interpolate": "^3.0.1"
64
- }
2
+ "name": "stk-table-vue",
3
+ "version": "0.6.4",
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
+ "docs:dev": "vitepress dev docs",
17
+ "docs:build": "vitepress build docs",
18
+ "docs:preview": "vitepress preview docs"
19
+ },
20
+ "keywords": [
21
+ "virtual table",
22
+ "vue",
23
+ "vue2",
24
+ "vue3",
25
+ "highlight",
26
+ "sticky",
27
+ "virtual",
28
+ "table",
29
+ "list"
30
+ ],
31
+ "files": [
32
+ "lib",
33
+ "src"
34
+ ],
35
+ "author": "japlus",
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "https://github.com/ja-plus/stk-table-vue"
39
+ },
40
+ "license": "MIT",
41
+ "devDependencies": {
42
+ "@types/d3-interpolate": "^3.0.4",
43
+ "@types/node": "^20.12.10",
44
+ "@typescript-eslint/eslint-plugin": "^7.7.0",
45
+ "@typescript-eslint/parser": "^7.7.0",
46
+ "@vitejs/plugin-vue": "^5.1.4",
47
+ "@vue/test-utils": "2.4.4",
48
+ "eslint": "^8.57.0",
49
+ "eslint-config-prettier": "^9.1.0",
50
+ "eslint-plugin-html": "^8.1.0",
51
+ "eslint-plugin-prettier": "^5.1.3",
52
+ "eslint-plugin-vue": "^9.25.0",
53
+ "happy-dom": "^12.10.3",
54
+ "less": "^4.2.0",
55
+ "postcss": "^8.4.47",
56
+ "postcss-discard-comments": "^6.0.2",
57
+ "postcss-preset-env": "^9.5.11",
58
+ "prettier": "^3.2.5",
59
+ "typescript": "^5.4.5",
60
+ "vite": "^5.4.10",
61
+ "vite-plugin-dts": "^4.3.0",
62
+ "vitepress": "^1.5.0",
63
+ "vitepress-demo-plugin": "^1.1.1",
64
+ "vitest": "^2.1.3",
65
+ "vue": "^3.5.12",
66
+ "vue-eslint-parser": "^9.4.2"
67
+ },
68
+ "dependencies": {
69
+ "d3-interpolate": "^3.0.1"
70
+ }
65
71
  }
@@ -62,7 +62,7 @@
62
62
  <!-- v for中最后一行才用 切割。TODO:不支持多级表头虚拟横向滚动 -->
63
63
  <th
64
64
  v-for="(col, colIndex) in virtualX_on && rowIndex === tableHeaders.length - 1 ? virtualX_columnPart : row"
65
- :key="col.dataIndex"
65
+ :key="colKeyGen(col)"
66
66
  :data-col-key="colKeyGen(col)"
67
67
  :draggable="isHeaderDraggable(col) ? 'true' : 'false'"
68
68
  :rowspan="virtualX_on ? 1 : col.rowSpan"
@@ -71,7 +71,7 @@
71
71
  :title="getHeaderTitle(col)"
72
72
  :class="[
73
73
  col.sorter ? 'sortable' : '',
74
- col.dataIndex === sortCol && sortOrderIndex !== 0 && 'sorter-' + sortSwitchOrder[sortOrderIndex],
74
+ colKeyGen(col) === sortCol && sortOrderIndex !== 0 && 'sorter-' + sortSwitchOrder[sortOrderIndex],
75
75
  col.headerClassName,
76
76
  fixedColClassMap.get(colKeyGen(col)),
77
77
  ]"
@@ -122,52 +122,46 @@
122
122
  <!--这个td用于配合虚拟滚动的th对应,防止列错位-->
123
123
  <td v-if="virtualX_on && fixedMode && headless" class="vt-x-left"></td>
124
124
  <template v-if="fixedMode && headless">
125
- <td v-for="col in virtualX_columnPart" :key="col.dataIndex" :style="cellStyleMap[TagType.TD].get(colKeyGen(col))"></td>
125
+ <td v-for="col in virtualX_columnPart" :key="colKeyGen(col)" :style="cellStyleMap[TagType.TD].get(colKeyGen(col))"></td>
126
126
  </template>
127
127
  </tr>
128
128
  <tr
129
129
  v-for="(row, rowIndex) in virtual_dataSourcePart"
130
- :id="stkTableId + '-' + (rowKey ? rowKeyGen(row) : virtualScroll.startIndex + rowIndex)"
130
+ :id="stkTableId + '-' + (rowKey ? rowKeyGen(row) : (virtual_on ? virtualScroll.startIndex : 0) + rowIndex)"
131
131
  ref="trRef"
132
- :key="rowKey ? rowKeyGen(row) : virtualScroll.startIndex + rowIndex"
133
- :data-row-key="rowKey ? rowKeyGen(row) : virtualScroll.startIndex + rowIndex"
132
+ :key="rowKey ? rowKeyGen(row) : (virtual_on ? virtualScroll.startIndex : 0) + rowIndex"
133
+ :data-row-key="rowKey ? rowKeyGen(row) : (virtual_on ? virtualScroll.startIndex : 0) + rowIndex"
134
134
  :class="{
135
135
  active: rowKey ? rowKeyGen(row) === currentRowKey : row === currentRow,
136
136
  hover: props.showTrHoverClass && (rowKey ? rowKeyGen(row) === currentHoverRowKey : row === currentHoverRowKey),
137
- [rowClassName(row, virtualScroll.startIndex + rowIndex)]: true,
137
+ [rowClassName(row, (virtual_on ? virtualScroll.startIndex : 0) + rowIndex)]: true,
138
138
  expanded: row?.__EXPANDED__,
139
- 'expanded-row': row && (row as ExpandedRow).__EXPANDED_ROW__,
139
+ 'expanded-row': row && row.__EXPANDED_ROW__,
140
140
  }"
141
141
  :style="{
142
- '--row-height':
143
- row &&
144
- (row as ExpandedRow).__EXPANDED_ROW__ &&
145
- virtual_on &&
146
- props.expandConfig?.height &&
147
- props.expandConfig?.height + 'px',
142
+ '--row-height': row && row.__EXPANDED_ROW__ && virtual_on && props.expandConfig?.height && props.expandConfig?.height + 'px',
148
143
  }"
149
144
  @click="e => onRowClick(e, row)"
150
145
  @dblclick="e => onRowDblclick(e, row)"
151
146
  @contextmenu="e => onRowMenu(e, row)"
152
147
  @mouseover="e => onTrMouseOver(e, row)"
153
- @drop="e => onTrDrop(e, virtualScroll.startIndex + rowIndex)"
148
+ @drop="e => onTrDrop(e, (virtual_on ? virtualScroll.startIndex : 0) + rowIndex)"
154
149
  >
155
150
  <!--这个td用于配合虚拟滚动的th对应,防止列错位-->
156
151
  <td v-if="virtualX_on" class="vt-x-left"></td>
157
- <td v-if="row && (row as ExpandedRow).__EXPANDED_ROW__" :colspan="virtualX_columnPart.length">
152
+ <td v-if="row && row.__EXPANDED_ROW__" :colspan="virtualX_columnPart.length">
158
153
  <!-- TODO: support wheel -->
159
154
  <div class="table-cell-wrapper">
160
- <slot name="expand" :row="(row as ExpandedRow).__EXPANDED_ROW__" :col="(row as ExpandedRow).__EXPANDED_COL__">
161
- {{ (row as ExpandedRow).__EXPANDED_ROW__?.[(row as ExpandedRow).__EXPANDED_COL__.dataIndex] ?? '' }}
155
+ <slot name="expand" :row="row.__EXPANDED_ROW__" :col="row.__EXPANDED_COL__">
156
+ {{ row.__EXPANDED_ROW__?.[row.__EXPANDED_COL__.dataIndex] ?? '' }}
162
157
  </slot>
163
158
  </div>
164
159
  </td>
165
160
  <template v-else>
166
161
  <td
167
162
  v-for="(col, colIndex) in virtualX_columnPart"
168
- :key="col.dataIndex"
169
- :data-index="col.dataIndex"
170
- :cell-key="rowKeyGen(row) + '--' + colKeyGen(col)"
163
+ :key="colKeyGen(col)"
164
+ :data-cell-key="cellKeyGen(row, col)"
171
165
  :style="cellStyleMap[TagType.TD].get(colKeyGen(col))"
172
166
  :class="[
173
167
  col.className,
@@ -196,7 +190,7 @@
196
190
  class="table-cell-wrapper"
197
191
  :col="col"
198
192
  :row="row"
199
- :rowIndex="virtualScroll.startIndex + rowIndex"
193
+ :rowIndex="(virtual_on ? virtualScroll.startIndex : 0) + rowIndex"
200
194
  :colIndex="colIndex"
201
195
  :cellValue="row?.[col.dataIndex]"
202
196
  :expanded="row?.__EXPANDED__ || null"
@@ -208,13 +202,13 @@
208
202
  :title="col.type !== 'seq' ? row?.[col.dataIndex] : ''"
209
203
  >
210
204
  <template v-if="col.type === 'seq'">
211
- {{ (props.seqConfig.startIndex || 0) + virtualScroll.startIndex + rowIndex + 1 }}
205
+ {{ (props.seqConfig.startIndex || 0) + (virtual_on ? virtualScroll.startIndex : 0) + rowIndex + 1 }}
212
206
  </template>
213
207
  <span v-else-if="col.type === 'expand'">
214
208
  {{ row?.[col.dataIndex] ?? '' }}
215
209
  </span>
216
210
  <template v-else-if="col.type === 'dragRow'">
217
- <DragHandle @dragstart="e => onTrDragStart(e, virtualScroll.startIndex + rowIndex)" />
211
+ <DragHandle @dragstart="e => onTrDragStart(e, (virtual_on ? virtualScroll.startIndex : 0) + rowIndex)" />
218
212
  <span>
219
213
  {{ row?.[col.dataIndex] ?? '' }}
220
214
  </span>
@@ -256,7 +250,6 @@ import {
256
250
  SeqConfig,
257
251
  SortConfig,
258
252
  SortOption,
259
- SortState,
260
253
  StkTableColumn,
261
254
  TagType,
262
255
  UniqKeyProp,
@@ -384,7 +377,7 @@ const props = withDefaults(
384
377
  optimizeVue2Scroll?: boolean;
385
378
  /** 排序配置 */
386
379
  sortConfig?: SortConfig<DT>;
387
- /** 隐藏头部title。可传入dataIndex数组 */
380
+ /** 隐藏头部title。可传入colKey数组 */
388
381
  hideHeaderTitle?: boolean | string[];
389
382
  /** 高亮配置 */
390
383
  highlightConfig?: HighlightConfig;
@@ -625,7 +618,7 @@ const currentHoverRowKey = ref(null);
625
618
  /** 当前hover的列的key */
626
619
  // const currentColHoverKey = ref(null);
627
620
 
628
- /** 排序的列dataIndex*/
621
+ /** sort colKey*/
629
622
  let sortCol = ref<keyof DT>();
630
623
  let sortOrderIndex = ref(0);
631
624
 
@@ -647,6 +640,26 @@ const tableHeaders = shallowRef<StkTableColumn<DT>[][]>([]);
647
640
  /** 若有多级表头时,最后一行的tableHeaders.内容是 props.columns 的引用集合 */
648
641
  const tableHeaderLast = shallowRef<StkTableColumn<DT>[]>([]);
649
642
 
643
+ /**
644
+ * 用于计算多级表头的tableHeaders。模拟rowSpan 位置的辅助数组。用于计算固定列。
645
+ * @eg
646
+ * ```
647
+ * | colspan3 |
648
+ * | rowspan2 | colspan2 |
649
+ * | rowspan2 | colspan1 | colspan1 |
650
+ * ```
651
+ * ---
652
+ * expect arr:
653
+ * ```
654
+ * const arr = [
655
+ * [col],
656
+ * [col2, col3],
657
+ * [col2, col4, col5],
658
+ * ]
659
+ * ```
660
+ */
661
+ const tableHeadersForCalc = shallowRef<PrivateStkTableColumn<DT>[][]>([]);
662
+
650
663
  const dataSourceCopy = shallowRef<DT[]>([...props.dataSource]);
651
664
 
652
665
  /**
@@ -696,7 +709,7 @@ const {
696
709
  } = useVirtualScroll({ tableContainerRef, trRef, props, dataSourceCopy, tableHeaderLast, tableHeaders, rowKeyGen });
697
710
 
698
711
  /** 获取固定列的位置 */
699
- const getFixedColPosition = useGetFixedColPosition({ colKeyGen, tableHeaders });
712
+ const getFixedColPosition = useGetFixedColPosition({ colKeyGen, tableHeadersForCalc });
700
713
 
701
714
  const getFixedStyle = useFixedStyle<DT>({
702
715
  props,
@@ -799,7 +812,7 @@ watch(
799
812
 
800
813
  if (sortCol.value) {
801
814
  // 排序
802
- const column = tableHeaderLast.value.find(it => it.dataIndex === sortCol.value);
815
+ const column = tableHeaderLast.value.find(it => colKeyGen.value(it) === sortCol.value);
803
816
  onColumnSort(column, false);
804
817
  }
805
818
  },
@@ -824,8 +837,8 @@ onMounted(() => {
824
837
  /** 处理默认排序 */
825
838
  function dealDefaultSorter() {
826
839
  if (!props.sortConfig.defaultSort) return;
827
- const { dataIndex, order, silent } = { silent: false, ...props.sortConfig.defaultSort };
828
- setSorter(dataIndex as string, order, { force: false, silent });
840
+ const { key, dataIndex, order, silent } = { silent: false, ...props.sortConfig.defaultSort };
841
+ setSorter((key || dataIndex) as string, order, { force: false, silent });
829
842
  }
830
843
 
831
844
  /**
@@ -833,7 +846,8 @@ function dealDefaultSorter() {
833
846
  */
834
847
  function dealColumns() {
835
848
  // reset
836
- let tableHeadersTemp: StkTableColumn<DT>[][] = [];
849
+ const tableHeadersTemp: StkTableColumn<DT>[][] = [];
850
+ const tableHeadersForCalcTemp: StkTableColumn<DT>[][] = [];
837
851
  let copyColumn = props.columns; // do not deep clone
838
852
  // relative 模式下不支持sticky列。因此就放在左右两侧。
839
853
  if (isRelativeMode.value) {
@@ -851,13 +865,18 @@ function dealColumns() {
851
865
  });
852
866
  copyColumn = [...leftCol, ...centerCol, ...rightCol];
853
867
  }
854
- const deep = howDeepTheHeader(copyColumn);
868
+ const maxDeep = howDeepTheHeader(copyColumn);
855
869
  const tempHeaderLast: StkTableColumn<DT>[] = [];
856
870
 
857
- if (deep > 1 && props.virtualX) {
871
+ if (maxDeep > 0 && props.virtualX) {
858
872
  console.error('多级表头不支持横向虚拟滚动');
859
873
  }
860
874
 
875
+ for (let i = 0; i <= maxDeep; i++) {
876
+ tableHeadersTemp[i] = [];
877
+ tableHeadersForCalcTemp[i] = [];
878
+ }
879
+
861
880
  /**
862
881
  * 展开columns
863
882
  * @param arr
@@ -870,9 +889,6 @@ function dealColumns() {
870
889
  parent: PrivateStkTableColumn<DT> | null,
871
890
  depth = 0 /* , parentFixed: 'left' | 'right' | null = null */,
872
891
  ) {
873
- if (!tableHeadersTemp[depth]) {
874
- tableHeadersTemp[depth] = [];
875
- }
876
892
  /** 所有子节点数量 */
877
893
  let allChildrenLen = 0;
878
894
  let allChildrenWidthSum = 0;
@@ -892,21 +908,27 @@ function dealColumns() {
892
908
  const [len, widthSum] = flat(col.children, col, depth + 1 /* , col.fixed */);
893
909
  colChildrenLen = len;
894
910
  colWidth = widthSum;
911
+ tableHeadersForCalcTemp[depth].push(col);
895
912
  } else {
896
913
  colWidth = getColWidth(col);
897
914
  tempHeaderLast.push(col); // 没有children的列作为colgroup
915
+ for (let i = depth; i <= maxDeep; i++) {
916
+ // 如有rowSpan 向下复制一个表头col,用于计算固定列
917
+ tableHeadersForCalcTemp[i].push(col);
918
+ }
898
919
  }
899
920
  // 回溯
921
+ col.__WIDTH__ = colWidth; //记录计算的列宽
900
922
  tableHeadersTemp[depth].push(col);
901
- const rowSpan = col.children ? 1 : deep - depth;
923
+ const rowSpan = col.children ? 1 : maxDeep - depth + 1;
902
924
  const colSpan = colChildrenLen;
903
- if (rowSpan !== 1) {
925
+ if (rowSpan > 1) {
904
926
  col.rowSpan = rowSpan;
905
927
  }
906
- if (colSpan !== 1) {
928
+ if (colSpan > 1) {
907
929
  col.colSpan = colSpan;
908
930
  }
909
- col.__WIDTH__ = colWidth; //记录计算的列宽
931
+
910
932
  allChildrenLen += colChildrenLen;
911
933
  allChildrenWidthSum += colWidth;
912
934
  });
@@ -914,9 +936,9 @@ function dealColumns() {
914
936
  }
915
937
 
916
938
  flat(copyColumn, null);
917
-
918
939
  tableHeaders.value = tableHeadersTemp;
919
940
  tableHeaderLast.value = tempHeaderLast;
941
+ tableHeadersForCalc.value = tableHeadersForCalcTemp;
920
942
  }
921
943
 
922
944
  /**
@@ -986,8 +1008,9 @@ const cellStyleMap = computed(() => {
986
1008
 
987
1009
  /** th title */
988
1010
  function getHeaderTitle(col: StkTableColumn<DT>): string {
1011
+ const colKey = colKeyGen.value(col);
989
1012
  // 不展示title
990
- if (props.hideHeaderTitle === true || (Array.isArray(props.hideHeaderTitle) && props.hideHeaderTitle.includes(col.dataIndex))) {
1013
+ if (props.hideHeaderTitle === true || (Array.isArray(props.hideHeaderTitle) && props.hideHeaderTitle.includes(colKey))) {
991
1014
  return '';
992
1015
  }
993
1016
  return col.title || '';
@@ -1009,28 +1032,37 @@ function onColumnSort(col: StkTableColumn<DT> | undefined | null, click = true,
1009
1032
  return;
1010
1033
  }
1011
1034
  options = { force: false, emit: false, ...options };
1012
- if (sortCol.value !== col.dataIndex) {
1035
+ const colKey = colKeyGen.value(col);
1036
+ if (sortCol.value !== colKey) {
1013
1037
  // 改变排序的列时,重置排序
1014
- sortCol.value = col.dataIndex;
1038
+ sortCol.value = colKey;
1015
1039
  sortOrderIndex.value = 0;
1016
1040
  }
1017
1041
  if (click) sortOrderIndex.value++;
1018
1042
  sortOrderIndex.value = sortOrderIndex.value % 3;
1019
1043
 
1020
1044
  let order = sortSwitchOrder[sortOrderIndex.value];
1021
- const sortConfig = props.sortConfig;
1045
+ const sortConfig = { ...props.sortConfig, ...col.sortConfig };
1022
1046
  const defaultSort = sortConfig.defaultSort;
1023
1047
 
1024
1048
  if (!order && defaultSort) {
1025
- if (!defaultSort.dataIndex) {
1026
- console.error('sortConfig.defaultSort.dataIndex is required');
1049
+ // if no order ,use default order
1050
+ const colKey = defaultSort.key || defaultSort.dataIndex;
1051
+ if (!colKey) {
1052
+ console.error('sortConfig.defaultSort key or dataIndex is required');
1027
1053
  return;
1028
1054
  }
1029
- // 没有排序时变成默认排序
1030
1055
  order = defaultSort.order || 'desc';
1031
1056
  sortOrderIndex.value = sortSwitchOrder.indexOf(order);
1032
- sortCol.value = defaultSort.dataIndex as string;
1033
- col = props.columns.find(item => item.dataIndex === defaultSort.dataIndex) || null;
1057
+ sortCol.value = colKey as string;
1058
+ col = null;
1059
+ for (const row of tableHeaders.value) {
1060
+ const c = row.find(item => colKeyGen.value(item) === colKey);
1061
+ if (c) {
1062
+ col = c;
1063
+ break;
1064
+ }
1065
+ }
1034
1066
  }
1035
1067
  if (!props.sortRemote || options.force) {
1036
1068
  const sortOption = col || defaultSort;
@@ -1247,24 +1279,24 @@ function setSelectedCell(row?: DT, col?: StkTableColumn<DT>, option = { silent:
1247
1279
  }
1248
1280
 
1249
1281
  /**
1250
- * 设置表头排序状态
1251
- * @param dataIndex 列字段
1282
+ * 设置表头排序状态。
1283
+ * @param colKey 列唯一键字段。如果你想要取消排序状态,请使用`resetSorter`
1252
1284
  * @param order 正序倒序
1253
1285
  * @param option.sortOption 指定排序参数。同 StkTableColumn 中排序相关字段。建议从columns中find得到。
1254
1286
  * @param option.sort 是否触发排序-默认true
1255
1287
  * @param option.silent 是否禁止触发回调-默认true
1256
1288
  * @param option.force 是否触发排序-默认true
1257
1289
  */
1258
- function setSorter(dataIndex: string, order: Order, option: { sortOption?: SortOption<DT>; force?: boolean; silent?: boolean; sort?: boolean } = {}) {
1290
+ function setSorter(colKey: string, order: Order, option: { sortOption?: SortOption<DT>; force?: boolean; silent?: boolean; sort?: boolean } = {}) {
1259
1291
  const newOption = { silent: true, sortOption: null, sort: true, ...option };
1260
- sortCol.value = dataIndex;
1292
+ sortCol.value = colKey;
1261
1293
  sortOrderIndex.value = sortSwitchOrder.indexOf(order);
1262
1294
 
1263
1295
  if (newOption.sort && dataSourceCopy.value?.length) {
1264
1296
  // 如果表格有数据,则进行排序
1265
- const column = newOption.sortOption || tableHeaderLast.value.find(it => it.dataIndex === sortCol.value);
1297
+ const column = newOption.sortOption || tableHeaderLast.value.find(it => colKeyGen.value(it) === sortCol.value);
1266
1298
  if (column) onColumnSort(column, false, { force: option.force ?? true, emit: !newOption.silent });
1267
- else console.warn('Can not find column by dataIndex:', sortCol.value);
1299
+ else console.warn('Can not find column by key:', sortCol.value);
1268
1300
  }
1269
1301
  return dataSourceCopy.value;
1270
1302
  }
@@ -1292,10 +1324,10 @@ function getTableData() {
1292
1324
  }
1293
1325
 
1294
1326
  /** get current sort info */
1295
- function getSortColumns(): Partial<SortState<DT>>[] {
1327
+ function getSortColumns() {
1296
1328
  const sortOrder = sortSwitchOrder[sortOrderIndex.value];
1297
1329
  if (!sortOrder) return [];
1298
- return [{ dataIndex: sortCol.value, order: sortOrder }];
1330
+ return [{ key: sortCol.value, order: sortOrder }];
1299
1331
  }
1300
1332
 
1301
1333
  /** click expended icon to toggle expand row */
@@ -1411,9 +1443,9 @@ defineExpose({
1411
1443
  */
1412
1444
  setHighlightDimRow,
1413
1445
  /**
1414
- * 表格排序列dataIndex
1446
+ * 表格排序列colKey
1415
1447
  *
1416
- * en: Table sort column dataIndex
1448
+ * en: Table sort column colKey
1417
1449
  */
1418
1450
  sortCol,
1419
1451
  /**
@@ -49,14 +49,7 @@
49
49
  display: flex;
50
50
  flex-direction: column;
51
51
  box-sizing: border-box;
52
- /**
53
- * border-left: 此方案用于减少cell 中border-left 的css选择。同时利于多级表头border-left问题。利于横向滚动border-left
54
- * - box-shadow inset 方案不生效,且占用属性。
55
- * - outline 方案绘制在图形外
56
- * - 绝对定位元素。需要根据滚动条位置动态计算。不合适。
57
- * - sticky 定位方案需要占用位置。高度为0。
58
- */
59
- border-left: 1px solid var(--border-color);
52
+
60
53
  /* 下面border用于表格内容不满高度时,绘制表格边界线 */
61
54
  background-image: var(--bg-border-top), var(--bg-border-right), var(--bg-border-bottom);
62
55
 
@@ -113,16 +106,15 @@
113
106
  }
114
107
  }
115
108
 
116
- &.border-h {
117
- --bg-border-right: linear-gradient(transparent, transparent);
118
- --bg-border-left: linear-gradient(transparent, transparent);
119
- }
120
-
121
- &.border-v {
122
- --bg-border-bottom: linear-gradient(transparent, transparent);
123
- }
124
-
125
109
  &.border {
110
+ /**
111
+ * border-left: 此方案用于减少cell 中border-left 的css选择。同时利于多级表头border-left问题。利于横向滚动border-left
112
+ * - box-shadow inset 方案不生效,且占用属性。
113
+ * - outline 方案绘制在图形外
114
+ * - 绝对定位元素。需要根据滚动条位置动态计算。不合适。
115
+ * - sticky 定位方案需要占用位置。高度为0。
116
+ */
117
+ border-left: 1px solid var(--border-color);
126
118
 
127
119
  th,
128
120
  td {
@@ -134,6 +126,19 @@
134
126
  }
135
127
  }
136
128
 
129
+ &.border-h {
130
+ border-left: none;
131
+ --bg-border-right: linear-gradient(transparent, transparent);
132
+ --bg-border-left: linear-gradient(transparent, transparent);
133
+ }
134
+
135
+ &.border-v {
136
+ --bg-border-bottom: linear-gradient(transparent, transparent);
137
+ --bg-border-top: linear-gradient(transparent, transparent);
138
+ }
139
+
140
+
141
+
137
142
  &.border-body-v {
138
143
  tbody {
139
144
  --bg-border-bottom: linear-gradient(transparent, transparent);
@@ -233,7 +238,7 @@
233
238
  }
234
239
 
235
240
  &.auto-row-height {
236
-
241
+
237
242
  tbody td {
238
243
  height: unset;
239
244
 
@@ -44,7 +44,6 @@ export type CustomCell<T extends CustomCellProps<U> | CustomHeaderCellProps<U>,
44
44
  export type StkTableColumn<T extends Record<string, any>> = {
45
45
  /**
46
46
  * 用于区分相同dataIndex 的列。
47
- * 需要自行配置colKey="(col: StkTableColumn<any>) => col.key ?? col.dataIndex"
48
47
  */
49
48
  key?: any;
50
49
  /**
@@ -78,6 +77,8 @@ export type StkTableColumn<T extends Record<string, any>> = {
78
77
  sortField?: keyof T;
79
78
  /** 排序方式。按数字/字符串 */
80
79
  sortType?: 'number' | 'string';
80
+ /** 配置当前列的排序规则 */
81
+ sortConfig?: Pick<SortConfig<T>, 'emptyToBottom' | 'stringLocaleCompare'>;
81
82
  /** 固定列 */
82
83
  fixed?: 'left' | 'right' | null;
83
84
  /** private */ rowSpan?: number;
@@ -155,6 +156,12 @@ export type SortConfig<T extends Record<string, any>> = {
155
156
  * 类似onMounted时,调用setSorter点了下表头。
156
157
  */
157
158
  defaultSort?: {
159
+ /**
160
+ * 列唯一键,
161
+ *
162
+ * 如果您配了 `props.colKey` 则这里表示的列唯一键的值
163
+ */
164
+ key?: StkTableColumn<T>['key'];
158
165
  dataIndex: StkTableColumn<T>['dataIndex'];
159
166
  order: Order;
160
167
  sortField?: StkTableColumn<T>['sortField'];
@@ -139,8 +139,9 @@ export function useColResize<DT extends Record<string, any>>({
139
139
  const { clientX } = e;
140
140
  let moveX = clientX - startX;
141
141
  const currentColWidth = getCalculatedColWidth(lastCol);
142
+ const minWidth = lastCol?.minWidth ?? props.colMinWidth;
142
143
  // 移动量不小于最小列宽
143
- if (currentColWidth + moveX < props.colMinWidth) {
144
+ if (currentColWidth + moveX < minWidth) {
144
145
  moveX = -currentColWidth;
145
146
  }
146
147
 
@@ -33,6 +33,7 @@ export function useFixedCol<DT extends Record<string, any>>({
33
33
  /** 固定列的class */
34
34
  const fixedColClassMap = computed(() => {
35
35
  const colMap = new Map();
36
+ // console.log('tableHeaderForCalc', tableHeaderForCalc.value);
36
37
  const fixedShadowColsValue = fixedShadowCols.value;
37
38
  tableHeaders.value.forEach(cols => {
38
39
  cols.forEach(col => {
@@ -43,7 +43,8 @@ export function useFixedStyle<DT extends Record<string, any>>({
43
43
  if (isRelativeMode.value) {
44
44
  style.top = virtualScroll.value.scrollTop + 'px';
45
45
  } else {
46
- style.top = depth * props.rowHeight + 'px';
46
+ const rowHeight = props.headerRowHeight ?? props.rowHeight;
47
+ style.top = depth * rowHeight + 'px';
47
48
  }
48
49
  }
49
50