stk-table-vue 0.6.2 → 0.6.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/README.md +1 -1
- package/lib/src/StkTable/StkTable.vue.d.ts +13 -10
- package/lib/src/StkTable/types/index.d.ts +6 -1
- package/lib/src/StkTable/useGetFixedColPosition.d.ts +2 -2
- package/lib/src/StkTable/useHighlight.d.ts +1 -1
- package/lib/src/StkTable/useThDrag.d.ts +1 -1
- package/lib/src/StkTable/utils/index.d.ts +2 -2
- package/lib/stk-table-vue.js +76 -54
- package/lib/style.css +11 -8
- package/package.json +69 -63
- package/src/StkTable/StkTable.vue +87 -50
- package/src/StkTable/style.less +23 -18
- package/src/StkTable/types/index.ts +6 -1
- package/src/StkTable/useFixedCol.ts +1 -0
- package/src/StkTable/useFixedStyle.ts +2 -1
- package/src/StkTable/useGetFixedColPosition.ts +8 -8
- package/src/StkTable/useHighlight.ts +3 -3
- package/src/StkTable/useThDrag.ts +2 -2
- package/src/StkTable/utils/index.ts +3 -3
- package/src/VirtualTreeSelect.vue +67 -33
package/package.json
CHANGED
|
@@ -1,65 +1,71 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
"
|
|
63
|
-
|
|
64
|
-
|
|
2
|
+
"name": "stk-table-vue",
|
|
3
|
+
"version": "0.6.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
|
+
"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
|
|
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
|
|
74
|
+
colKeyGen(col) === sortCol && sortOrderIndex !== 0 && 'sorter-' + sortSwitchOrder[sortOrderIndex],
|
|
75
75
|
col.headerClassName,
|
|
76
76
|
fixedColClassMap.get(colKeyGen(col)),
|
|
77
77
|
]"
|
|
@@ -122,19 +122,19 @@
|
|
|
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
|
|
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
139
|
'expanded-row': row && (row as ExpandedRow).__EXPANDED_ROW__,
|
|
140
140
|
}"
|
|
@@ -150,7 +150,7 @@
|
|
|
150
150
|
@dblclick="e => onRowDblclick(e, row)"
|
|
151
151
|
@contextmenu="e => onRowMenu(e, row)"
|
|
152
152
|
@mouseover="e => onTrMouseOver(e, row)"
|
|
153
|
-
@drop="e => onTrDrop(e, virtualScroll.startIndex + rowIndex)"
|
|
153
|
+
@drop="e => onTrDrop(e, (virtual_on ? virtualScroll.startIndex : 0) + rowIndex)"
|
|
154
154
|
>
|
|
155
155
|
<!--这个td用于配合虚拟滚动的th对应,防止列错位-->
|
|
156
156
|
<td v-if="virtualX_on" class="vt-x-left"></td>
|
|
@@ -165,9 +165,8 @@
|
|
|
165
165
|
<template v-else>
|
|
166
166
|
<td
|
|
167
167
|
v-for="(col, colIndex) in virtualX_columnPart"
|
|
168
|
-
:key="col
|
|
169
|
-
:data-
|
|
170
|
-
:cell-key="rowKeyGen(row) + '--' + colKeyGen(col)"
|
|
168
|
+
:key="colKeyGen(col)"
|
|
169
|
+
:data-cell-key="cellKeyGen(row, col)"
|
|
171
170
|
:style="cellStyleMap[TagType.TD].get(colKeyGen(col))"
|
|
172
171
|
:class="[
|
|
173
172
|
col.className,
|
|
@@ -196,7 +195,7 @@
|
|
|
196
195
|
class="table-cell-wrapper"
|
|
197
196
|
:col="col"
|
|
198
197
|
:row="row"
|
|
199
|
-
:rowIndex="virtualScroll.startIndex + rowIndex"
|
|
198
|
+
:rowIndex="(virtual_on ? virtualScroll.startIndex : 0) + rowIndex"
|
|
200
199
|
:colIndex="colIndex"
|
|
201
200
|
:cellValue="row?.[col.dataIndex]"
|
|
202
201
|
:expanded="row?.__EXPANDED__ || null"
|
|
@@ -208,13 +207,13 @@
|
|
|
208
207
|
:title="col.type !== 'seq' ? row?.[col.dataIndex] : ''"
|
|
209
208
|
>
|
|
210
209
|
<template v-if="col.type === 'seq'">
|
|
211
|
-
{{ (props.seqConfig.startIndex || 0) + virtualScroll.startIndex + rowIndex + 1 }}
|
|
210
|
+
{{ (props.seqConfig.startIndex || 0) + (virtual_on ? virtualScroll.startIndex : 0) + rowIndex + 1 }}
|
|
212
211
|
</template>
|
|
213
212
|
<span v-else-if="col.type === 'expand'">
|
|
214
213
|
{{ row?.[col.dataIndex] ?? '' }}
|
|
215
214
|
</span>
|
|
216
215
|
<template v-else-if="col.type === 'dragRow'">
|
|
217
|
-
<DragHandle @dragstart="e => onTrDragStart(e, virtualScroll.startIndex + rowIndex)" />
|
|
216
|
+
<DragHandle @dragstart="e => onTrDragStart(e, (virtual_on ? virtualScroll.startIndex : 0) + rowIndex)" />
|
|
218
217
|
<span>
|
|
219
218
|
{{ row?.[col.dataIndex] ?? '' }}
|
|
220
219
|
</span>
|
|
@@ -256,7 +255,6 @@ import {
|
|
|
256
255
|
SeqConfig,
|
|
257
256
|
SortConfig,
|
|
258
257
|
SortOption,
|
|
259
|
-
SortState,
|
|
260
258
|
StkTableColumn,
|
|
261
259
|
TagType,
|
|
262
260
|
UniqKeyProp,
|
|
@@ -384,7 +382,7 @@ const props = withDefaults(
|
|
|
384
382
|
optimizeVue2Scroll?: boolean;
|
|
385
383
|
/** 排序配置 */
|
|
386
384
|
sortConfig?: SortConfig<DT>;
|
|
387
|
-
/** 隐藏头部title。可传入
|
|
385
|
+
/** 隐藏头部title。可传入colKey数组 */
|
|
388
386
|
hideHeaderTitle?: boolean | string[];
|
|
389
387
|
/** 高亮配置 */
|
|
390
388
|
highlightConfig?: HighlightConfig;
|
|
@@ -625,7 +623,7 @@ const currentHoverRowKey = ref(null);
|
|
|
625
623
|
/** 当前hover的列的key */
|
|
626
624
|
// const currentColHoverKey = ref(null);
|
|
627
625
|
|
|
628
|
-
/**
|
|
626
|
+
/** sort colKey*/
|
|
629
627
|
let sortCol = ref<keyof DT>();
|
|
630
628
|
let sortOrderIndex = ref(0);
|
|
631
629
|
|
|
@@ -647,6 +645,26 @@ const tableHeaders = shallowRef<StkTableColumn<DT>[][]>([]);
|
|
|
647
645
|
/** 若有多级表头时,最后一行的tableHeaders.内容是 props.columns 的引用集合 */
|
|
648
646
|
const tableHeaderLast = shallowRef<StkTableColumn<DT>[]>([]);
|
|
649
647
|
|
|
648
|
+
/**
|
|
649
|
+
* 用于计算多级表头的tableHeaders。模拟rowSpan 位置的辅助数组。用于计算固定列。
|
|
650
|
+
* @eg
|
|
651
|
+
* ```
|
|
652
|
+
* | colspan3 |
|
|
653
|
+
* | rowspan2 | colspan2 |
|
|
654
|
+
* | rowspan2 | colspan1 | colspan1 |
|
|
655
|
+
* ```
|
|
656
|
+
* ---
|
|
657
|
+
* expect arr:
|
|
658
|
+
* ```
|
|
659
|
+
* const arr = [
|
|
660
|
+
* [col],
|
|
661
|
+
* [col2, col3],
|
|
662
|
+
* [col2, col4, col5],
|
|
663
|
+
* ]
|
|
664
|
+
* ```
|
|
665
|
+
*/
|
|
666
|
+
const tableHeadersForCalc = shallowRef<PrivateStkTableColumn<DT>[][]>([]);
|
|
667
|
+
|
|
650
668
|
const dataSourceCopy = shallowRef<DT[]>([...props.dataSource]);
|
|
651
669
|
|
|
652
670
|
/**
|
|
@@ -696,7 +714,7 @@ const {
|
|
|
696
714
|
} = useVirtualScroll({ tableContainerRef, trRef, props, dataSourceCopy, tableHeaderLast, tableHeaders, rowKeyGen });
|
|
697
715
|
|
|
698
716
|
/** 获取固定列的位置 */
|
|
699
|
-
const getFixedColPosition = useGetFixedColPosition({ colKeyGen,
|
|
717
|
+
const getFixedColPosition = useGetFixedColPosition({ colKeyGen, tableHeadersForCalc });
|
|
700
718
|
|
|
701
719
|
const getFixedStyle = useFixedStyle<DT>({
|
|
702
720
|
props,
|
|
@@ -799,7 +817,7 @@ watch(
|
|
|
799
817
|
|
|
800
818
|
if (sortCol.value) {
|
|
801
819
|
// 排序
|
|
802
|
-
const column = tableHeaderLast.value.find(it => it
|
|
820
|
+
const column = tableHeaderLast.value.find(it => colKeyGen.value(it) === sortCol.value);
|
|
803
821
|
onColumnSort(column, false);
|
|
804
822
|
}
|
|
805
823
|
},
|
|
@@ -824,8 +842,8 @@ onMounted(() => {
|
|
|
824
842
|
/** 处理默认排序 */
|
|
825
843
|
function dealDefaultSorter() {
|
|
826
844
|
if (!props.sortConfig.defaultSort) return;
|
|
827
|
-
const { dataIndex, order, silent } = { silent: false, ...props.sortConfig.defaultSort };
|
|
828
|
-
setSorter(dataIndex as string, order, { force: false, silent });
|
|
845
|
+
const { key, dataIndex, order, silent } = { silent: false, ...props.sortConfig.defaultSort };
|
|
846
|
+
setSorter((key || dataIndex) as string, order, { force: false, silent });
|
|
829
847
|
}
|
|
830
848
|
|
|
831
849
|
/**
|
|
@@ -833,7 +851,8 @@ function dealDefaultSorter() {
|
|
|
833
851
|
*/
|
|
834
852
|
function dealColumns() {
|
|
835
853
|
// reset
|
|
836
|
-
|
|
854
|
+
const tableHeadersTemp: StkTableColumn<DT>[][] = [];
|
|
855
|
+
const tableHeadersForCalcTemp: StkTableColumn<DT>[][] = [];
|
|
837
856
|
let copyColumn = props.columns; // do not deep clone
|
|
838
857
|
// relative 模式下不支持sticky列。因此就放在左右两侧。
|
|
839
858
|
if (isRelativeMode.value) {
|
|
@@ -851,13 +870,18 @@ function dealColumns() {
|
|
|
851
870
|
});
|
|
852
871
|
copyColumn = [...leftCol, ...centerCol, ...rightCol];
|
|
853
872
|
}
|
|
854
|
-
const
|
|
873
|
+
const maxDeep = howDeepTheHeader(copyColumn);
|
|
855
874
|
const tempHeaderLast: StkTableColumn<DT>[] = [];
|
|
856
875
|
|
|
857
|
-
if (
|
|
876
|
+
if (maxDeep > 0 && props.virtualX) {
|
|
858
877
|
console.error('多级表头不支持横向虚拟滚动');
|
|
859
878
|
}
|
|
860
879
|
|
|
880
|
+
for (let i = 0; i <= maxDeep; i++) {
|
|
881
|
+
tableHeadersTemp[i] = [];
|
|
882
|
+
tableHeadersForCalcTemp[i] = [];
|
|
883
|
+
}
|
|
884
|
+
|
|
861
885
|
/**
|
|
862
886
|
* 展开columns
|
|
863
887
|
* @param arr
|
|
@@ -870,9 +894,6 @@ function dealColumns() {
|
|
|
870
894
|
parent: PrivateStkTableColumn<DT> | null,
|
|
871
895
|
depth = 0 /* , parentFixed: 'left' | 'right' | null = null */,
|
|
872
896
|
) {
|
|
873
|
-
if (!tableHeadersTemp[depth]) {
|
|
874
|
-
tableHeadersTemp[depth] = [];
|
|
875
|
-
}
|
|
876
897
|
/** 所有子节点数量 */
|
|
877
898
|
let allChildrenLen = 0;
|
|
878
899
|
let allChildrenWidthSum = 0;
|
|
@@ -892,21 +913,27 @@ function dealColumns() {
|
|
|
892
913
|
const [len, widthSum] = flat(col.children, col, depth + 1 /* , col.fixed */);
|
|
893
914
|
colChildrenLen = len;
|
|
894
915
|
colWidth = widthSum;
|
|
916
|
+
tableHeadersForCalcTemp[depth].push(col);
|
|
895
917
|
} else {
|
|
896
918
|
colWidth = getColWidth(col);
|
|
897
919
|
tempHeaderLast.push(col); // 没有children的列作为colgroup
|
|
920
|
+
for (let i = depth; i <= maxDeep; i++) {
|
|
921
|
+
// 如有rowSpan 向下复制一个表头col,用于计算固定列
|
|
922
|
+
tableHeadersForCalcTemp[i].push(col);
|
|
923
|
+
}
|
|
898
924
|
}
|
|
899
925
|
// 回溯
|
|
926
|
+
col.__WIDTH__ = colWidth; //记录计算的列宽
|
|
900
927
|
tableHeadersTemp[depth].push(col);
|
|
901
|
-
const rowSpan = col.children ? 1 :
|
|
928
|
+
const rowSpan = col.children ? 1 : maxDeep - depth + 1;
|
|
902
929
|
const colSpan = colChildrenLen;
|
|
903
|
-
if (rowSpan
|
|
930
|
+
if (rowSpan > 1) {
|
|
904
931
|
col.rowSpan = rowSpan;
|
|
905
932
|
}
|
|
906
|
-
if (colSpan
|
|
933
|
+
if (colSpan > 1) {
|
|
907
934
|
col.colSpan = colSpan;
|
|
908
935
|
}
|
|
909
|
-
|
|
936
|
+
|
|
910
937
|
allChildrenLen += colChildrenLen;
|
|
911
938
|
allChildrenWidthSum += colWidth;
|
|
912
939
|
});
|
|
@@ -914,9 +941,9 @@ function dealColumns() {
|
|
|
914
941
|
}
|
|
915
942
|
|
|
916
943
|
flat(copyColumn, null);
|
|
917
|
-
|
|
918
944
|
tableHeaders.value = tableHeadersTemp;
|
|
919
945
|
tableHeaderLast.value = tempHeaderLast;
|
|
946
|
+
tableHeadersForCalc.value = tableHeadersForCalcTemp;
|
|
920
947
|
}
|
|
921
948
|
|
|
922
949
|
/**
|
|
@@ -986,8 +1013,9 @@ const cellStyleMap = computed(() => {
|
|
|
986
1013
|
|
|
987
1014
|
/** th title */
|
|
988
1015
|
function getHeaderTitle(col: StkTableColumn<DT>): string {
|
|
1016
|
+
const colKey = colKeyGen.value(col);
|
|
989
1017
|
// 不展示title
|
|
990
|
-
if (props.hideHeaderTitle === true || (Array.isArray(props.hideHeaderTitle) && props.hideHeaderTitle.includes(
|
|
1018
|
+
if (props.hideHeaderTitle === true || (Array.isArray(props.hideHeaderTitle) && props.hideHeaderTitle.includes(colKey))) {
|
|
991
1019
|
return '';
|
|
992
1020
|
}
|
|
993
1021
|
return col.title || '';
|
|
@@ -1009,9 +1037,10 @@ function onColumnSort(col: StkTableColumn<DT> | undefined | null, click = true,
|
|
|
1009
1037
|
return;
|
|
1010
1038
|
}
|
|
1011
1039
|
options = { force: false, emit: false, ...options };
|
|
1012
|
-
|
|
1040
|
+
const colKey = colKeyGen.value(col);
|
|
1041
|
+
if (sortCol.value !== colKey) {
|
|
1013
1042
|
// 改变排序的列时,重置排序
|
|
1014
|
-
sortCol.value =
|
|
1043
|
+
sortCol.value = colKey;
|
|
1015
1044
|
sortOrderIndex.value = 0;
|
|
1016
1045
|
}
|
|
1017
1046
|
if (click) sortOrderIndex.value++;
|
|
@@ -1022,15 +1051,23 @@ function onColumnSort(col: StkTableColumn<DT> | undefined | null, click = true,
|
|
|
1022
1051
|
const defaultSort = sortConfig.defaultSort;
|
|
1023
1052
|
|
|
1024
1053
|
if (!order && defaultSort) {
|
|
1025
|
-
if
|
|
1026
|
-
|
|
1054
|
+
// if no order ,use default order
|
|
1055
|
+
const colKey = defaultSort.key || defaultSort.dataIndex;
|
|
1056
|
+
if (!colKey) {
|
|
1057
|
+
console.error('sortConfig.defaultSort key or dataIndex is required');
|
|
1027
1058
|
return;
|
|
1028
1059
|
}
|
|
1029
|
-
// 没有排序时变成默认排序
|
|
1030
1060
|
order = defaultSort.order || 'desc';
|
|
1031
1061
|
sortOrderIndex.value = sortSwitchOrder.indexOf(order);
|
|
1032
|
-
sortCol.value =
|
|
1033
|
-
col =
|
|
1062
|
+
sortCol.value = colKey as string;
|
|
1063
|
+
col = null;
|
|
1064
|
+
for (const row of tableHeaders.value) {
|
|
1065
|
+
const c = row.find(item => colKeyGen.value(item) === colKey);
|
|
1066
|
+
if (c) {
|
|
1067
|
+
col = c;
|
|
1068
|
+
break;
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1034
1071
|
}
|
|
1035
1072
|
if (!props.sortRemote || options.force) {
|
|
1036
1073
|
const sortOption = col || defaultSort;
|
|
@@ -1247,24 +1284,24 @@ function setSelectedCell(row?: DT, col?: StkTableColumn<DT>, option = { silent:
|
|
|
1247
1284
|
}
|
|
1248
1285
|
|
|
1249
1286
|
/**
|
|
1250
|
-
*
|
|
1251
|
-
* @param
|
|
1287
|
+
* 设置表头排序状态。
|
|
1288
|
+
* @param colKey 列唯一键字段。如果你想要取消排序状态,请使用`resetSorter`
|
|
1252
1289
|
* @param order 正序倒序
|
|
1253
1290
|
* @param option.sortOption 指定排序参数。同 StkTableColumn 中排序相关字段。建议从columns中find得到。
|
|
1254
1291
|
* @param option.sort 是否触发排序-默认true
|
|
1255
1292
|
* @param option.silent 是否禁止触发回调-默认true
|
|
1256
1293
|
* @param option.force 是否触发排序-默认true
|
|
1257
1294
|
*/
|
|
1258
|
-
function setSorter(
|
|
1295
|
+
function setSorter(colKey: string, order: Order, option: { sortOption?: SortOption<DT>; force?: boolean; silent?: boolean; sort?: boolean } = {}) {
|
|
1259
1296
|
const newOption = { silent: true, sortOption: null, sort: true, ...option };
|
|
1260
|
-
sortCol.value =
|
|
1297
|
+
sortCol.value = colKey;
|
|
1261
1298
|
sortOrderIndex.value = sortSwitchOrder.indexOf(order);
|
|
1262
1299
|
|
|
1263
1300
|
if (newOption.sort && dataSourceCopy.value?.length) {
|
|
1264
1301
|
// 如果表格有数据,则进行排序
|
|
1265
|
-
const column = newOption.sortOption || tableHeaderLast.value.find(it => it
|
|
1302
|
+
const column = newOption.sortOption || tableHeaderLast.value.find(it => colKeyGen.value(it) === sortCol.value);
|
|
1266
1303
|
if (column) onColumnSort(column, false, { force: option.force ?? true, emit: !newOption.silent });
|
|
1267
|
-
else console.warn('Can not find column by
|
|
1304
|
+
else console.warn('Can not find column by key:', sortCol.value);
|
|
1268
1305
|
}
|
|
1269
1306
|
return dataSourceCopy.value;
|
|
1270
1307
|
}
|
|
@@ -1292,10 +1329,10 @@ function getTableData() {
|
|
|
1292
1329
|
}
|
|
1293
1330
|
|
|
1294
1331
|
/** get current sort info */
|
|
1295
|
-
function getSortColumns()
|
|
1332
|
+
function getSortColumns() {
|
|
1296
1333
|
const sortOrder = sortSwitchOrder[sortOrderIndex.value];
|
|
1297
1334
|
if (!sortOrder) return [];
|
|
1298
|
-
return [{
|
|
1335
|
+
return [{ key: sortCol.value, order: sortOrder }];
|
|
1299
1336
|
}
|
|
1300
1337
|
|
|
1301
1338
|
/** click expended icon to toggle expand row */
|
|
@@ -1411,9 +1448,9 @@ defineExpose({
|
|
|
1411
1448
|
*/
|
|
1412
1449
|
setHighlightDimRow,
|
|
1413
1450
|
/**
|
|
1414
|
-
* 表格排序列
|
|
1451
|
+
* 表格排序列colKey
|
|
1415
1452
|
*
|
|
1416
|
-
* en: Table sort column
|
|
1453
|
+
* en: Table sort column colKey
|
|
1417
1454
|
*/
|
|
1418
1455
|
sortCol,
|
|
1419
1456
|
/**
|
package/src/StkTable/style.less
CHANGED
|
@@ -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
|
/**
|
|
@@ -155,6 +154,12 @@ export type SortConfig<T extends Record<string, any>> = {
|
|
|
155
154
|
* 类似onMounted时,调用setSorter点了下表头。
|
|
156
155
|
*/
|
|
157
156
|
defaultSort?: {
|
|
157
|
+
/**
|
|
158
|
+
* 列唯一键,
|
|
159
|
+
*
|
|
160
|
+
* 如果您配了 `props.colKey` 则这里表示的列唯一键的值
|
|
161
|
+
*/
|
|
162
|
+
key?: StkTableColumn<T>['key'];
|
|
158
163
|
dataIndex: StkTableColumn<T>['dataIndex'];
|
|
159
164
|
order: Order;
|
|
160
165
|
sortField?: StkTableColumn<T>['sortField'];
|
|
@@ -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
|
-
|
|
46
|
+
const rowHeight = props.headerRowHeight ?? props.rowHeight;
|
|
47
|
+
style.top = depth * rowHeight + 'px';
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
50
|
|
|
@@ -4,7 +4,7 @@ import { getCalculatedColWidth } from './utils/constRefUtils';
|
|
|
4
4
|
|
|
5
5
|
type Params<T extends Record<string, any>> = {
|
|
6
6
|
colKeyGen: ComputedRef<(col: StkTableColumn<T>) => UniqKey>;
|
|
7
|
-
|
|
7
|
+
tableHeadersForCalc: ShallowRef<StkTableColumn<T>[][]>;
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -12,21 +12,21 @@ type Params<T extends Record<string, any>> = {
|
|
|
12
12
|
* - col.fixed = left 则得到距离左侧的距离
|
|
13
13
|
* - col.fixed = right 则得到距离右侧的距离
|
|
14
14
|
*/
|
|
15
|
-
export function useGetFixedColPosition<DT extends Record<string, any>>({
|
|
15
|
+
export function useGetFixedColPosition<DT extends Record<string, any>>({ tableHeadersForCalc, colKeyGen }: Params<DT>) {
|
|
16
16
|
/** 固定列fixed左侧或者右侧的距离 */
|
|
17
17
|
const getFixedColPosition = computed(() => {
|
|
18
|
-
/**
|
|
18
|
+
/** colKey 作为唯一标识 */
|
|
19
19
|
const colKeyStore: Record<string, number> = {};
|
|
20
|
-
/** 没有
|
|
20
|
+
/** 没有 colKey 的多级表头列,使用对象引用做标识 */
|
|
21
21
|
const refStore = new WeakMap<StkTableColumn<DT>, number>();
|
|
22
|
-
|
|
22
|
+
tableHeadersForCalc.value.forEach(cols => {
|
|
23
23
|
let left = 0;
|
|
24
24
|
/**遍历右侧fixed时,因为left已经遍历过一次了。所以,可以拿到right遍历边界 */
|
|
25
25
|
let rightStartIndex = 0;
|
|
26
26
|
for (let i = 0; i < cols.length; i++) {
|
|
27
27
|
const item = cols[i];
|
|
28
28
|
if (item.fixed === 'left') {
|
|
29
|
-
const colKey = colKeyGen.value(item)
|
|
29
|
+
const colKey = colKeyGen.value(item);
|
|
30
30
|
if (colKey) {
|
|
31
31
|
colKeyStore[colKey] = left;
|
|
32
32
|
} else {
|
|
@@ -42,7 +42,7 @@ export function useGetFixedColPosition<DT extends Record<string, any>>({ tableHe
|
|
|
42
42
|
let right = 0;
|
|
43
43
|
for (let i = cols.length - 1; i >= rightStartIndex; i--) {
|
|
44
44
|
const item = cols[i];
|
|
45
|
-
const colKey = colKeyGen.value(item)
|
|
45
|
+
const colKey = colKeyGen.value(item);
|
|
46
46
|
if (item.fixed === 'right') {
|
|
47
47
|
if (colKey) {
|
|
48
48
|
colKeyStore[colKey] = right;
|
|
@@ -55,7 +55,7 @@ export function useGetFixedColPosition<DT extends Record<string, any>>({ tableHe
|
|
|
55
55
|
});
|
|
56
56
|
|
|
57
57
|
return (col: StkTableColumn<any>) => {
|
|
58
|
-
const colKey = colKeyGen.value(col)
|
|
58
|
+
const colKey = colKeyGen.value(col);
|
|
59
59
|
return colKey ? colKeyStore[colKey] : refStore.get(col) || 0;
|
|
60
60
|
};
|
|
61
61
|
});
|