stk-table-vue 0.2.5 → 0.2.7
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 +31 -4
- package/lib/src/StkTable/StkTable.vue.d.ts +17 -4
- package/lib/src/StkTable/types/index.d.ts +11 -1
- package/lib/src/StkTable/useFixedCol.d.ts +3 -2
- package/lib/src/StkTable/useFixedStyle.d.ts +2 -2
- package/lib/src/StkTable/useHighlight.d.ts +3 -1
- package/lib/stk-table-vue.js +85 -58
- package/package.json +60 -60
- package/src/StkTable/StkTable.vue +63 -54
- package/src/StkTable/types/index.ts +12 -1
- package/src/StkTable/useFixedCol.ts +27 -23
- package/src/StkTable/useFixedStyle.ts +6 -4
- package/src/StkTable/useHighlight.ts +7 -3
package/README.md
CHANGED
|
@@ -40,7 +40,8 @@ repo:
|
|
|
40
40
|
* [] 非虚拟滚动时,大数据分批加载。
|
|
41
41
|
* [x] vue2.7支持(引入源码使用)。
|
|
42
42
|
- [x] `props.optimizeVue2Scroll` 优化vue2虚拟滚动流畅度。
|
|
43
|
-
* [] `props.emptyCellText` 支持传入函数。
|
|
43
|
+
* [x] `props.emptyCellText` 支持传入函数。
|
|
44
|
+
* [] 支持配置高亮参数。
|
|
44
45
|
|
|
45
46
|
|
|
46
47
|
## Usage
|
|
@@ -135,7 +136,7 @@ export type StkProps = {
|
|
|
135
136
|
/** 列唯一键 */
|
|
136
137
|
colKey?: UniqKeyProp;
|
|
137
138
|
/** 空值展示文字 */
|
|
138
|
-
emptyCellText?: string;
|
|
139
|
+
emptyCellText?: string | ((option: { row: DT; col: StkTableColumn<DT> }) => string);
|
|
139
140
|
/** 暂无数据兜底高度是否撑满 */
|
|
140
141
|
noDataFull?: boolean;
|
|
141
142
|
/** 是否展示暂无数据 */
|
|
@@ -148,8 +149,6 @@ export type StkProps = {
|
|
|
148
149
|
showOverflow?: boolean;
|
|
149
150
|
/** 是否增加行hover class */
|
|
150
151
|
showTrHoverClass?: boolean;
|
|
151
|
-
/** 表头是否可拖动 */
|
|
152
|
-
headerDrag?: boolean;
|
|
153
152
|
/** 表头是否可拖动。支持回调函数。 */
|
|
154
153
|
headerDrag?: boolean | ((col: StkTableColumn<DT>) => boolean);
|
|
155
154
|
/**
|
|
@@ -348,6 +347,30 @@ export type StkTableColumn<T extends Record<string, any>> = {
|
|
|
348
347
|
```
|
|
349
348
|
|
|
350
349
|
|
|
350
|
+
### StkTableColumn.SortConfig
|
|
351
|
+
```ts
|
|
352
|
+
/** 排序配置 */
|
|
353
|
+
export type SortConfig<T extends Record<string, any>> = {
|
|
354
|
+
/** 空值始终排在列表末尾 */
|
|
355
|
+
emptyToBottom?: boolean;
|
|
356
|
+
/**
|
|
357
|
+
* 默认排序(1.初始化时触发 2.排序方向为null时触发)
|
|
358
|
+
* 类似onMounted时,调用setSorter点了下表头。
|
|
359
|
+
*/
|
|
360
|
+
defaultSort?: {
|
|
361
|
+
dataIndex: keyof T;
|
|
362
|
+
order: Order;
|
|
363
|
+
/** 是否禁止触发sort-change事件。默认false,表示触发事件。 */
|
|
364
|
+
silent?: boolean;
|
|
365
|
+
};
|
|
366
|
+
/**
|
|
367
|
+
* string排序是否使用 String.prototype.localCompare
|
|
368
|
+
* 默认true (&$&应该false)
|
|
369
|
+
*/
|
|
370
|
+
stringLocaleCompare?: boolean;
|
|
371
|
+
};
|
|
372
|
+
```
|
|
373
|
+
|
|
351
374
|
### Example
|
|
352
375
|
```vue
|
|
353
376
|
<template>
|
|
@@ -420,3 +443,7 @@ export type StkTableColumn<T extends Record<string, any>> = {
|
|
|
420
443
|
### 鼠标悬浮表头时,不展示title
|
|
421
444
|
* 将 `StkTableColumn` 中的 `title` 字段置为 "" 空字符串。这样th中就没有title了。
|
|
422
445
|
* 使用 `StkTableColumn` 中的 `customHeaderCell` 属性中,自定义表头渲染。
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
## Other
|
|
449
|
+
* `$*$` 兼容注释
|
|
@@ -16,9 +16,11 @@ declare function setCurrentRow(rowKey: string, option?: {
|
|
|
16
16
|
* @param option.sortOption 指定排序参数。同 StkTableColumn 中排序相关字段。建议从columns中find得到。
|
|
17
17
|
* @param option.sort 是否触发排序-默认true
|
|
18
18
|
* @param option.silent 是否禁止触发回调-默认true
|
|
19
|
+
* @param option.force 是否触发排序-默认true
|
|
19
20
|
*/
|
|
20
21
|
declare function setSorter(dataIndex: string, order: Order, option?: {
|
|
21
22
|
sortOption?: SortOption<DT>;
|
|
23
|
+
force?: boolean;
|
|
22
24
|
silent?: boolean;
|
|
23
25
|
sort?: boolean;
|
|
24
26
|
}): any[];
|
|
@@ -65,7 +67,10 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
|
|
|
65
67
|
/** 列唯一键 */
|
|
66
68
|
colKey?: UniqKeyProp | undefined;
|
|
67
69
|
/** 空值展示文字 */
|
|
68
|
-
emptyCellText?: string |
|
|
70
|
+
emptyCellText?: string | ((option: {
|
|
71
|
+
row: any;
|
|
72
|
+
col: StkTableColumn<any>;
|
|
73
|
+
}) => string) | undefined;
|
|
69
74
|
/** 暂无数据兜底高度是否撑满 */
|
|
70
75
|
noDataFull?: boolean | undefined;
|
|
71
76
|
/** 是否展示暂无数据 */
|
|
@@ -163,7 +168,9 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
|
|
|
163
168
|
/** 设置高亮渐暗单元格 */
|
|
164
169
|
setHighlightDimCell: (rowKeyValue: string, dataIndex: string) => void;
|
|
165
170
|
/** 设置高亮渐暗行 */
|
|
166
|
-
setHighlightDimRow: (rowKeyValues: import("./types/index").UniqKey[]
|
|
171
|
+
setHighlightDimRow: (rowKeyValues: import("./types/index").UniqKey[], option?: {
|
|
172
|
+
useCss?: boolean | undefined;
|
|
173
|
+
}) => void;
|
|
167
174
|
/** 表格排序列dataIndex */
|
|
168
175
|
sortCol: import("vue").Ref<string | null | undefined>;
|
|
169
176
|
/** 获取当前排序状态 */
|
|
@@ -225,7 +232,10 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
|
|
|
225
232
|
/** 列唯一键 */
|
|
226
233
|
colKey?: UniqKeyProp | undefined;
|
|
227
234
|
/** 空值展示文字 */
|
|
228
|
-
emptyCellText?: string |
|
|
235
|
+
emptyCellText?: string | ((option: {
|
|
236
|
+
row: any;
|
|
237
|
+
col: StkTableColumn<any>;
|
|
238
|
+
}) => string) | undefined;
|
|
229
239
|
/** 暂无数据兜底高度是否撑满 */
|
|
230
240
|
noDataFull?: boolean | undefined;
|
|
231
241
|
/** 是否展示暂无数据 */
|
|
@@ -345,7 +355,10 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
|
|
|
345
355
|
dataSource: any[];
|
|
346
356
|
rowKey: UniqKeyProp;
|
|
347
357
|
colKey: UniqKeyProp;
|
|
348
|
-
emptyCellText: string
|
|
358
|
+
emptyCellText: string | ((option: {
|
|
359
|
+
row: any;
|
|
360
|
+
col: StkTableColumn<any>;
|
|
361
|
+
}) => string);
|
|
349
362
|
noDataFull: boolean;
|
|
350
363
|
showNoData: boolean;
|
|
351
364
|
sortRemote: boolean;
|
|
@@ -78,10 +78,15 @@ export type UniqKeyProp = UniqKey | UniqKeyFun;
|
|
|
78
78
|
export type SortConfig<T extends Record<string, any>> = {
|
|
79
79
|
/** 空值始终排在列表末尾 */
|
|
80
80
|
emptyToBottom?: boolean;
|
|
81
|
-
/**
|
|
81
|
+
/**
|
|
82
|
+
* 默认排序(1.初始化时触发 2.排序方向为null时触发)
|
|
83
|
+
* 类似onMounted时,调用setSorter点了下表头。
|
|
84
|
+
*/
|
|
82
85
|
defaultSort?: {
|
|
83
86
|
dataIndex: keyof T;
|
|
84
87
|
order: Order;
|
|
88
|
+
/** 是否禁止触发sort-change事件。默认false,表示触发事件。 */
|
|
89
|
+
silent?: boolean;
|
|
85
90
|
};
|
|
86
91
|
/**
|
|
87
92
|
* string排序是否使用 String.prototype.localCompare
|
|
@@ -89,4 +94,9 @@ export type SortConfig<T extends Record<string, any>> = {
|
|
|
89
94
|
*/
|
|
90
95
|
stringLocaleCompare?: boolean;
|
|
91
96
|
};
|
|
97
|
+
/** th td类型 */
|
|
98
|
+
export declare const enum TagType {
|
|
99
|
+
TH = 0,
|
|
100
|
+
TD = 1
|
|
101
|
+
}
|
|
92
102
|
export {};
|
|
@@ -2,6 +2,7 @@ import { Ref } from 'vue';
|
|
|
2
2
|
import { StkTableColumn } from './types';
|
|
3
3
|
type Params<T extends Record<string, any>> = {
|
|
4
4
|
props: any;
|
|
5
|
+
colKeyGen: (col: StkTableColumn<T>) => string;
|
|
5
6
|
tableHeaderLast: Ref<StkTableColumn<T>[]>;
|
|
6
7
|
tableContainer: Ref<HTMLDivElement | undefined>;
|
|
7
8
|
};
|
|
@@ -9,9 +10,9 @@ type Params<T extends Record<string, any>> = {
|
|
|
9
10
|
* 固定列处理
|
|
10
11
|
* @returns
|
|
11
12
|
*/
|
|
12
|
-
export declare function useFixedCol<DT extends Record<string, any>>({ props, tableHeaderLast, tableContainer }: Params<DT>): {
|
|
13
|
+
export declare function useFixedCol<DT extends Record<string, any>>({ props, colKeyGen, tableHeaderLast, tableContainer }: Params<DT>): {
|
|
13
14
|
/** 固定列class */
|
|
14
|
-
|
|
15
|
+
fixedColClassMap: import("vue").ComputedRef<Map<any, any>>;
|
|
15
16
|
/** 处理固定列阴影 */
|
|
16
17
|
dealFixedColShadow: () => void;
|
|
17
18
|
/** 滚动条变化时,更新需要展示阴影的列 */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CSSProperties, Ref } from 'vue';
|
|
2
|
-
import { StkTableColumn } from './types';
|
|
2
|
+
import { StkTableColumn, TagType } from './types';
|
|
3
3
|
import { VirtualScrollStore, VirtualScrollXStore } from './useVirtualScroll';
|
|
4
4
|
type Options<T extends Record<string, any>> = {
|
|
5
5
|
props: any;
|
|
@@ -15,6 +15,6 @@ type Options<T extends Record<string, any>> = {
|
|
|
15
15
|
* @returns
|
|
16
16
|
*/
|
|
17
17
|
export declare function useFixedStyle<DT extends Record<string, any>>({ props, tableHeaders, virtualScroll, virtualScrollX, virtualX_on, virtualX_offsetRight, }: Options<DT>): {
|
|
18
|
-
getFixedStyle: (tagType:
|
|
18
|
+
getFixedStyle: (tagType: TagType, col: StkTableColumn<DT>, depth?: number) => CSSProperties;
|
|
19
19
|
};
|
|
20
20
|
export {};
|
|
@@ -20,7 +20,9 @@ type HighlightRowStore = {
|
|
|
20
20
|
*/
|
|
21
21
|
export declare function useHighlight({ props, tableContainer }: Params): {
|
|
22
22
|
highlightRowStore: Ref<Record<UniqKey, HighlightRowStore>>;
|
|
23
|
-
setHighlightDimRow: (rowKeyValues: UniqKey[]
|
|
23
|
+
setHighlightDimRow: (rowKeyValues: UniqKey[], option?: {
|
|
24
|
+
useCss?: boolean;
|
|
25
|
+
}) => void;
|
|
24
26
|
setHighlightDimCell: (rowKeyValue: string, dataIndex: string) => void;
|
|
25
27
|
};
|
|
26
28
|
export {};
|
package/lib/stk-table-vue.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { onMounted, onBeforeUnmount, watch, ref, computed, defineComponent,
|
|
1
|
+
import { onMounted, onBeforeUnmount, watch, ref, shallowRef, computed, defineComponent, toRaw, openBlock, createElementBlock, normalizeClass, unref, normalizeStyle, withDirectives, createElementVNode, vShow, Fragment, renderList, createCommentVNode, createBlock, resolveDynamicComponent, renderSlot, toDisplayString, createTextVNode } from "vue";
|
|
2
2
|
import { interpolateRgb } from "d3-interpolate";
|
|
3
3
|
const Default_Col_Width = "100";
|
|
4
4
|
const Default_Table_Height = 100;
|
|
@@ -20,6 +20,11 @@ try {
|
|
|
20
20
|
console.error("Cannot get Chrome version", e);
|
|
21
21
|
}
|
|
22
22
|
const Is_Legacy_Mode = _chromeVersion < 56;
|
|
23
|
+
var TagType = /* @__PURE__ */ ((TagType2) => {
|
|
24
|
+
TagType2[TagType2["TH"] = 0] = "TH";
|
|
25
|
+
TagType2[TagType2["TD"] = 1] = "TD";
|
|
26
|
+
return TagType2;
|
|
27
|
+
})(TagType || {});
|
|
23
28
|
function useAutoResize({ tableContainer, initVirtualScroll, props, debounceMs }) {
|
|
24
29
|
let resizeObserver = null;
|
|
25
30
|
onMounted(() => {
|
|
@@ -325,16 +330,30 @@ function useColResize({
|
|
|
325
330
|
onThResizeMouseUp
|
|
326
331
|
};
|
|
327
332
|
}
|
|
328
|
-
function useFixedCol({ props, tableHeaderLast, tableContainer }) {
|
|
333
|
+
function useFixedCol({ props, colKeyGen, tableHeaderLast, tableContainer }) {
|
|
329
334
|
const fixedShadow = ref({
|
|
330
335
|
showL: false,
|
|
331
336
|
showR: false
|
|
332
337
|
});
|
|
333
|
-
|
|
338
|
+
const fixedShadowCols = shallowRef([]);
|
|
339
|
+
const fixedColClassMap = computed(() => {
|
|
340
|
+
const colMap = /* @__PURE__ */ new Map();
|
|
341
|
+
props.columns.forEach((col) => {
|
|
342
|
+
const { showR, showL } = fixedShadow.value;
|
|
343
|
+
const showShadow = props.fixedColShadow && col.fixed && (showL && col.fixed === "left" || showR && col.fixed === "right") && fixedShadowCols.value.includes(col);
|
|
344
|
+
const classObj = {
|
|
345
|
+
"fixed-cell": col.fixed,
|
|
346
|
+
["fixed-cell--" + col.fixed]: col.fixed,
|
|
347
|
+
"fixed-cell--shadow": showShadow
|
|
348
|
+
};
|
|
349
|
+
colMap.set(colKeyGen(col), classObj);
|
|
350
|
+
});
|
|
351
|
+
return colMap;
|
|
352
|
+
});
|
|
334
353
|
function dealFixedColShadow() {
|
|
335
354
|
if (!props.fixedColShadow)
|
|
336
355
|
return;
|
|
337
|
-
fixedShadowCols = [];
|
|
356
|
+
fixedShadowCols.value = [];
|
|
338
357
|
let lastLeftCol = null;
|
|
339
358
|
for (let i = tableHeaderLast.value.length - 1; i >= 0; i--) {
|
|
340
359
|
const col = tableHeaderLast.value[i];
|
|
@@ -346,27 +365,17 @@ function useFixedCol({ props, tableHeaderLast, tableContainer }) {
|
|
|
346
365
|
let node = { __PARENT__: lastLeftCol };
|
|
347
366
|
while (node = node.__PARENT__) {
|
|
348
367
|
if (node.fixed) {
|
|
349
|
-
fixedShadowCols.push(node);
|
|
368
|
+
fixedShadowCols.value.push(node);
|
|
350
369
|
}
|
|
351
370
|
}
|
|
352
371
|
const lastRightCol = tableHeaderLast.value.find((it) => it.fixed === "right");
|
|
353
372
|
node = { __PARENT__: lastRightCol };
|
|
354
373
|
while (node = node.__PARENT__) {
|
|
355
374
|
if (node.fixed) {
|
|
356
|
-
fixedShadowCols.push(node);
|
|
375
|
+
fixedShadowCols.value.push(node);
|
|
357
376
|
}
|
|
358
377
|
}
|
|
359
378
|
}
|
|
360
|
-
function getFixedColClass(col) {
|
|
361
|
-
const { showR, showL } = fixedShadow.value;
|
|
362
|
-
const showShadow = props.fixedColShadow && col.fixed && (showL && col.fixed === "left" || showR && col.fixed === "right") && fixedShadowCols.includes(col);
|
|
363
|
-
const classObj = {
|
|
364
|
-
"fixed-cell": col.fixed,
|
|
365
|
-
["fixed-cell--" + col.fixed]: col.fixed,
|
|
366
|
-
"fixed-cell--shadow": showShadow
|
|
367
|
-
};
|
|
368
|
-
return classObj;
|
|
369
|
-
}
|
|
370
379
|
function updateFixedShadow() {
|
|
371
380
|
if (!props.fixedColShadow)
|
|
372
381
|
return;
|
|
@@ -376,7 +385,7 @@ function useFixedCol({ props, tableHeaderLast, tableContainer }) {
|
|
|
376
385
|
}
|
|
377
386
|
return {
|
|
378
387
|
/** 固定列class */
|
|
379
|
-
|
|
388
|
+
fixedColClassMap,
|
|
380
389
|
/** 处理固定列阴影 */
|
|
381
390
|
dealFixedColShadow,
|
|
382
391
|
/** 滚动条变化时,更新需要展示阴影的列 */
|
|
@@ -436,7 +445,7 @@ function useFixedStyle({
|
|
|
436
445
|
} else {
|
|
437
446
|
style.position = "sticky";
|
|
438
447
|
}
|
|
439
|
-
if (tagType ===
|
|
448
|
+
if (tagType === TagType.TH) {
|
|
440
449
|
if (Is_Legacy_Mode) {
|
|
441
450
|
style.top = virtualScroll.value.scrollTop + depth * props.rowHeight + "px";
|
|
442
451
|
} else {
|
|
@@ -499,6 +508,7 @@ function useHighlight({ props, tableContainer }) {
|
|
|
499
508
|
highlightDimRowKeys.delete(rowKeyValue);
|
|
500
509
|
}
|
|
501
510
|
});
|
|
511
|
+
highlightRowStore.value = { ...highlightRowStore.value };
|
|
502
512
|
if (highlightDimRowKeys.size > 0) {
|
|
503
513
|
recursion();
|
|
504
514
|
} else {
|
|
@@ -527,16 +537,16 @@ function useHighlight({ props, tableContainer }) {
|
|
|
527
537
|
}, Highlight_Duration)
|
|
528
538
|
);
|
|
529
539
|
}
|
|
530
|
-
function setHighlightDimRow(rowKeyValues) {
|
|
540
|
+
function setHighlightDimRow(rowKeyValues, option = {}) {
|
|
531
541
|
var _a, _b;
|
|
532
542
|
if (!Array.isArray(rowKeyValues))
|
|
533
543
|
rowKeyValues = [rowKeyValues];
|
|
534
|
-
if (props.virtual) {
|
|
544
|
+
if (props.virtual && !option.useCss) {
|
|
535
545
|
const nowTs = Date.now();
|
|
536
546
|
for (let i = 0; i < rowKeyValues.length; i++) {
|
|
537
547
|
const rowKeyValue = rowKeyValues[i];
|
|
538
548
|
highlightRowStore.value[rowKeyValue] = {
|
|
539
|
-
bgc:
|
|
549
|
+
bgc: highlightFrom.value,
|
|
540
550
|
bgc_progress: 0,
|
|
541
551
|
bgc_progress_ms: nowTs
|
|
542
552
|
};
|
|
@@ -954,7 +964,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
954
964
|
dataSource: { default: () => [] },
|
|
955
965
|
rowKey: { type: [String, Number, Function], default: "" },
|
|
956
966
|
colKey: { type: [String, Number, Function], default: "dataIndex" },
|
|
957
|
-
emptyCellText: { default: "--" },
|
|
967
|
+
emptyCellText: { type: [String, Function], default: "--" },
|
|
958
968
|
noDataFull: { type: Boolean, default: false },
|
|
959
969
|
showNoData: { type: Boolean, default: true },
|
|
960
970
|
sortRemote: { type: Boolean, default: false },
|
|
@@ -990,6 +1000,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
990
1000
|
const tableHeaders = ref([]);
|
|
991
1001
|
const tableHeaderLast = ref([]);
|
|
992
1002
|
const dataSourceCopy = shallowRef([...props.dataSource]);
|
|
1003
|
+
const getEmptyCellText = computed(() => {
|
|
1004
|
+
if (typeof props.emptyCellText === "string") {
|
|
1005
|
+
return () => props.emptyCellText;
|
|
1006
|
+
} else {
|
|
1007
|
+
return (col, row) => props.emptyCellText({ row, col });
|
|
1008
|
+
}
|
|
1009
|
+
});
|
|
993
1010
|
const rowKeyGenStore = /* @__PURE__ */ new WeakMap();
|
|
994
1011
|
const { isColResizing, onThResizeMouseDown } = useColResize({
|
|
995
1012
|
props,
|
|
@@ -1034,8 +1051,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1034
1051
|
virtualScrollX,
|
|
1035
1052
|
tableHeaders
|
|
1036
1053
|
});
|
|
1037
|
-
const {
|
|
1054
|
+
const { fixedColClassMap, dealFixedColShadow, updateFixedShadow } = useFixedCol({
|
|
1038
1055
|
props,
|
|
1056
|
+
colKeyGen,
|
|
1039
1057
|
tableContainer,
|
|
1040
1058
|
tableHeaderLast
|
|
1041
1059
|
});
|
|
@@ -1080,8 +1098,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1080
1098
|
function dealDefaultSorter() {
|
|
1081
1099
|
if (!props.sortConfig.defaultSort)
|
|
1082
1100
|
return;
|
|
1083
|
-
const { dataIndex, order } = props.sortConfig.defaultSort;
|
|
1084
|
-
setSorter(dataIndex, order);
|
|
1101
|
+
const { dataIndex, order, silent } = { silent: false, ...props.sortConfig.defaultSort };
|
|
1102
|
+
setSorter(dataIndex, order, { force: false, silent });
|
|
1085
1103
|
}
|
|
1086
1104
|
function dealColumns() {
|
|
1087
1105
|
tableHeaders.value = [];
|
|
@@ -1149,33 +1167,42 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1149
1167
|
function colKeyGen(col) {
|
|
1150
1168
|
return typeof props.colKey === "function" ? props.colKey(col) : col[props.colKey];
|
|
1151
1169
|
}
|
|
1152
|
-
|
|
1153
|
-
const
|
|
1154
|
-
const
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1170
|
+
const cellStyleMap = computed(() => {
|
|
1171
|
+
const thMap = /* @__PURE__ */ new Map();
|
|
1172
|
+
const tdMap = /* @__PURE__ */ new Map();
|
|
1173
|
+
tableHeaders.value.forEach((cols, depth) => {
|
|
1174
|
+
cols.forEach((col) => {
|
|
1175
|
+
const colKey = colKeyGen(col);
|
|
1176
|
+
const width = getColWidthStr(col);
|
|
1177
|
+
const style = {
|
|
1178
|
+
width
|
|
1179
|
+
};
|
|
1180
|
+
if (props.colResizable) {
|
|
1181
|
+
style.minWidth = width;
|
|
1182
|
+
style.maxWidth = width;
|
|
1183
|
+
} else {
|
|
1184
|
+
style.minWidth = getColWidthStr(col, "minWidth") ?? width;
|
|
1185
|
+
style.maxWidth = getColWidthStr(col, "maxWidth") ?? width;
|
|
1186
|
+
}
|
|
1187
|
+
const thStyle = {
|
|
1188
|
+
...style,
|
|
1189
|
+
...getFixedStyle(TagType.TH, col, depth),
|
|
1190
|
+
textAlign: col.headerAlign
|
|
1191
|
+
};
|
|
1192
|
+
const tdStyle = {
|
|
1193
|
+
...style,
|
|
1194
|
+
...getFixedStyle(TagType.TD, col, depth),
|
|
1195
|
+
textAlign: col.align
|
|
1196
|
+
};
|
|
1197
|
+
thMap.set(colKey, thStyle);
|
|
1198
|
+
tdMap.set(colKey, tdStyle);
|
|
1199
|
+
});
|
|
1200
|
+
});
|
|
1201
|
+
return {
|
|
1202
|
+
[TagType.TH]: thMap,
|
|
1203
|
+
[TagType.TD]: tdMap
|
|
1171
1204
|
};
|
|
1172
|
-
|
|
1173
|
-
style.textAlign = col.headerAlign;
|
|
1174
|
-
} else if (tagType === 2) {
|
|
1175
|
-
style.textAlign = col.align;
|
|
1176
|
-
}
|
|
1177
|
-
return style;
|
|
1178
|
-
}
|
|
1205
|
+
});
|
|
1179
1206
|
function getHeaderTitle(col) {
|
|
1180
1207
|
if (props.hideHeaderTitle === true || Array.isArray(props.hideHeaderTitle) && props.hideHeaderTitle.includes(col.dataIndex)) {
|
|
1181
1208
|
return "";
|
|
@@ -1288,7 +1315,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1288
1315
|
if (newOption.sort && ((_a = dataSourceCopy.value) == null ? void 0 : _a.length)) {
|
|
1289
1316
|
const column = newOption.sortOption || tableHeaderLast.value.find((it) => it.dataIndex === sortCol.value);
|
|
1290
1317
|
if (column)
|
|
1291
|
-
onColumnSort(column, false, { force: true, emit: !newOption.silent });
|
|
1318
|
+
onColumnSort(column, false, { force: option.force ?? true, emit: !newOption.silent });
|
|
1292
1319
|
else
|
|
1293
1320
|
console.warn("Can not find column by dataIndex:", sortCol.value);
|
|
1294
1321
|
}
|
|
@@ -1402,14 +1429,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1402
1429
|
draggable: unref(isHeaderDraggable)(col) ? "true" : "false",
|
|
1403
1430
|
rowspan: unref(virtualX_on) ? 1 : col.rowSpan,
|
|
1404
1431
|
colspan: col.colSpan,
|
|
1405
|
-
style: normalizeStyle(
|
|
1432
|
+
style: normalizeStyle(cellStyleMap.value[unref(TagType).TH].get(colKeyGen(col))),
|
|
1406
1433
|
title: getHeaderTitle(col),
|
|
1407
1434
|
class: normalizeClass([
|
|
1408
1435
|
col.sorter ? "sortable" : "",
|
|
1409
1436
|
col.dataIndex === unref(sortCol) && unref(sortOrderIndex) !== 0 && "sorter-" + sortSwitchOrder[unref(sortOrderIndex)],
|
|
1410
1437
|
_ctx.showHeaderOverflow ? "text-overflow" : "",
|
|
1411
1438
|
col.headerClassName,
|
|
1412
|
-
unref(
|
|
1439
|
+
unref(fixedColClassMap).get(colKeyGen(col))
|
|
1413
1440
|
]),
|
|
1414
1441
|
onClick: (e) => {
|
|
1415
1442
|
onColumnSort(col);
|
|
@@ -1467,7 +1494,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1467
1494
|
_ctx.fixedMode && _ctx.headless ? (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(unref(virtualX_columnPart), (col) => {
|
|
1468
1495
|
return openBlock(), createElementBlock("td", {
|
|
1469
1496
|
key: col.dataIndex,
|
|
1470
|
-
style: normalizeStyle(
|
|
1497
|
+
style: normalizeStyle(cellStyleMap.value[unref(TagType).TD].get(colKeyGen(col)))
|
|
1471
1498
|
}, null, 4);
|
|
1472
1499
|
}), 128)) : createCommentVNode("", true)
|
|
1473
1500
|
], 4)) : createCommentVNode("", true),
|
|
@@ -1494,8 +1521,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1494
1521
|
return openBlock(), createElementBlock("td", {
|
|
1495
1522
|
key: col.dataIndex,
|
|
1496
1523
|
"data-index": col.dataIndex,
|
|
1497
|
-
class: normalizeClass([col.className, _ctx.showOverflow ? "text-overflow" : "", unref(
|
|
1498
|
-
style: normalizeStyle(
|
|
1524
|
+
class: normalizeClass([col.className, _ctx.showOverflow ? "text-overflow" : "", unref(fixedColClassMap).get(colKeyGen(col))]),
|
|
1525
|
+
style: normalizeStyle(cellStyleMap.value[unref(TagType).TD].get(colKeyGen(col))),
|
|
1499
1526
|
onClick: (e) => onCellClick(e, row, col)
|
|
1500
1527
|
}, [
|
|
1501
1528
|
col.customCell ? (openBlock(), createBlock(resolveDynamicComponent(col.customCell), {
|
|
@@ -1507,7 +1534,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1507
1534
|
key: 1,
|
|
1508
1535
|
class: "table-cell-wrapper",
|
|
1509
1536
|
title: row[col.dataIndex]
|
|
1510
|
-
}, toDisplayString(row[col.dataIndex] ??
|
|
1537
|
+
}, toDisplayString(row[col.dataIndex] ?? getEmptyCellText.value(col, row)), 9, _hoisted_14))
|
|
1511
1538
|
], 14, _hoisted_13);
|
|
1512
1539
|
}), 128))
|
|
1513
1540
|
], 46, _hoisted_11);
|
package/package.json
CHANGED
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "stk-table-vue",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "Simple realtime virtual table for vue3&vue2.7",
|
|
5
|
-
"main": "./lib/stk-table-vue.js",
|
|
6
|
-
"types": "./lib/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
|
-
"highlight",
|
|
21
|
-
"sticky"
|
|
22
|
-
],
|
|
23
|
-
"files": [
|
|
24
|
-
"lib",
|
|
25
|
-
"src"
|
|
26
|
-
],
|
|
27
|
-
"author": "japlus",
|
|
28
|
-
"repository": {
|
|
29
|
-
"type": "git",
|
|
30
|
-
"url": "https://gitee.com/japlus/stk-table-vue"
|
|
31
|
-
},
|
|
32
|
-
"license": "MIT",
|
|
33
|
-
"devDependencies": {
|
|
34
|
-
"@types/d3-interpolate": "^3.0.4",
|
|
35
|
-
"@types/node": "^20.11.14",
|
|
36
|
-
"@typescript-eslint/eslint-plugin": "^6.14.0",
|
|
37
|
-
"@typescript-eslint/parser": "^6.14.0",
|
|
38
|
-
"@vitejs/plugin-vue": "^5.0.3",
|
|
39
|
-
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
|
40
|
-
"@vue/test-utils": "2.4.4",
|
|
41
|
-
"eslint": "^8.55.0",
|
|
42
|
-
"eslint-config-prettier": "^9.1.0",
|
|
43
|
-
"eslint-plugin-html": "^7.1.0",
|
|
44
|
-
"eslint-plugin-prettier": "^5.0.1",
|
|
45
|
-
"eslint-plugin-vue": "^9.19.2",
|
|
46
|
-
"happy-dom": "^12.10.3",
|
|
47
|
-
"less": "^4.2.0",
|
|
48
|
-
"postcss-discard-comments": "^6.0.1",
|
|
49
|
-
"postcss-preset-env": "^9.3.0",
|
|
50
|
-
"prettier": "^3.1.1",
|
|
51
|
-
"typescript": "^5.3.3",
|
|
52
|
-
"vite": "^5.1.4",
|
|
53
|
-
"vite-plugin-dts": "^3.7.3",
|
|
54
|
-
"vitest": "^1.1.0",
|
|
55
|
-
"vue": "^3.4.19",
|
|
56
|
-
"vue-eslint-parser": "^9.3.2"
|
|
57
|
-
},
|
|
58
|
-
"dependencies": {
|
|
59
|
-
"d3-interpolate": "^3.0.1"
|
|
60
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "stk-table-vue",
|
|
3
|
+
"version": "0.2.7",
|
|
4
|
+
"description": "Simple realtime virtual table for vue3&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
|
+
"highlight",
|
|
21
|
+
"sticky"
|
|
22
|
+
],
|
|
23
|
+
"files": [
|
|
24
|
+
"lib",
|
|
25
|
+
"src"
|
|
26
|
+
],
|
|
27
|
+
"author": "japlus",
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://gitee.com/japlus/stk-table-vue"
|
|
31
|
+
},
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/d3-interpolate": "^3.0.4",
|
|
35
|
+
"@types/node": "^20.11.14",
|
|
36
|
+
"@typescript-eslint/eslint-plugin": "^6.14.0",
|
|
37
|
+
"@typescript-eslint/parser": "^6.14.0",
|
|
38
|
+
"@vitejs/plugin-vue": "^5.0.3",
|
|
39
|
+
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
|
40
|
+
"@vue/test-utils": "2.4.4",
|
|
41
|
+
"eslint": "^8.55.0",
|
|
42
|
+
"eslint-config-prettier": "^9.1.0",
|
|
43
|
+
"eslint-plugin-html": "^7.1.0",
|
|
44
|
+
"eslint-plugin-prettier": "^5.0.1",
|
|
45
|
+
"eslint-plugin-vue": "^9.19.2",
|
|
46
|
+
"happy-dom": "^12.10.3",
|
|
47
|
+
"less": "^4.2.0",
|
|
48
|
+
"postcss-discard-comments": "^6.0.1",
|
|
49
|
+
"postcss-preset-env": "^9.3.0",
|
|
50
|
+
"prettier": "^3.1.1",
|
|
51
|
+
"typescript": "^5.3.3",
|
|
52
|
+
"vite": "^5.1.4",
|
|
53
|
+
"vite-plugin-dts": "^3.7.3",
|
|
54
|
+
"vitest": "^1.1.0",
|
|
55
|
+
"vue": "^3.4.19",
|
|
56
|
+
"vue-eslint-parser": "^9.3.2"
|
|
57
|
+
},
|
|
58
|
+
"dependencies": {
|
|
59
|
+
"d3-interpolate": "^3.0.1"
|
|
60
|
+
}
|
|
61
61
|
}
|
|
@@ -60,14 +60,14 @@
|
|
|
60
60
|
:draggable="isHeaderDraggable(col) ? 'true' : 'false'"
|
|
61
61
|
:rowspan="virtualX_on ? 1 : col.rowSpan"
|
|
62
62
|
:colspan="col.colSpan"
|
|
63
|
-
:style="
|
|
63
|
+
:style="cellStyleMap[TagType.TH].get(colKeyGen(col))"
|
|
64
64
|
:title="getHeaderTitle(col)"
|
|
65
65
|
:class="[
|
|
66
66
|
col.sorter ? 'sortable' : '',
|
|
67
67
|
col.dataIndex === sortCol && sortOrderIndex !== 0 && 'sorter-' + sortSwitchOrder[sortOrderIndex],
|
|
68
68
|
showHeaderOverflow ? 'text-overflow' : '',
|
|
69
69
|
col.headerClassName,
|
|
70
|
-
|
|
70
|
+
fixedColClassMap.get(colKeyGen(col)),
|
|
71
71
|
]"
|
|
72
72
|
@click="
|
|
73
73
|
e => {
|
|
@@ -135,7 +135,7 @@
|
|
|
135
135
|
<!--这个td用于配合虚拟滚动的th对应,防止列错位-->
|
|
136
136
|
<td v-if="virtualX_on && fixedMode && headless" class="virtual-x-left" style="padding: 0"></td>
|
|
137
137
|
<template v-if="fixedMode && headless">
|
|
138
|
-
<td v-for="col in virtualX_columnPart" :key="col.dataIndex" :style="
|
|
138
|
+
<td v-for="col in virtualX_columnPart" :key="col.dataIndex" :style="cellStyleMap[TagType.TD].get(colKeyGen(col))"></td
|
|
139
139
|
></template>
|
|
140
140
|
</tr>
|
|
141
141
|
<tr
|
|
@@ -161,13 +161,13 @@
|
|
|
161
161
|
v-for="col in virtualX_columnPart"
|
|
162
162
|
:key="col.dataIndex"
|
|
163
163
|
:data-index="col.dataIndex"
|
|
164
|
-
:class="[col.className, showOverflow ? 'text-overflow' : '',
|
|
165
|
-
:style="
|
|
164
|
+
:class="[col.className, showOverflow ? 'text-overflow' : '', fixedColClassMap.get(colKeyGen(col))]"
|
|
165
|
+
:style="cellStyleMap[TagType.TD].get(colKeyGen(col))"
|
|
166
166
|
@click="e => onCellClick(e, row, col)"
|
|
167
167
|
>
|
|
168
168
|
<component :is="col.customCell" v-if="col.customCell" :col="col" :row="row" :cell-value="row[col.dataIndex]" />
|
|
169
169
|
<div v-else class="table-cell-wrapper" :title="row[col.dataIndex]">
|
|
170
|
-
{{ row[col.dataIndex] ??
|
|
170
|
+
{{ row[col.dataIndex] ?? getEmptyCellText(col, row) }}
|
|
171
171
|
</div>
|
|
172
172
|
</td>
|
|
173
173
|
</tr>
|
|
@@ -189,9 +189,9 @@
|
|
|
189
189
|
* [] 计算的高亮颜色,挂在数据源上对象上,若多个表格使用同一个数据源对象会有问题。需要深拷贝。(解决方案:获取组件uid)
|
|
190
190
|
* [] highlight-row 颜色不能恢复到active的颜色
|
|
191
191
|
*/
|
|
192
|
-
import { CSSProperties, onMounted, ref, shallowRef, toRaw, watch } from 'vue';
|
|
192
|
+
import { CSSProperties, computed, onMounted, ref, shallowRef, toRaw, watch } from 'vue';
|
|
193
193
|
import { Default_Row_Height } from './const';
|
|
194
|
-
import { Order, SortConfig, SortOption, SortState, StkTableColumn, UniqKeyProp } from './types/index';
|
|
194
|
+
import { Order, SortConfig, SortOption, SortState, StkTableColumn, TagType, UniqKeyProp } from './types/index';
|
|
195
195
|
import { useAutoResize } from './useAutoResize';
|
|
196
196
|
import { useColResize } from './useColResize';
|
|
197
197
|
import { useFixedCol } from './useFixedCol';
|
|
@@ -239,7 +239,7 @@ const props = withDefaults(
|
|
|
239
239
|
/** 列唯一键 */
|
|
240
240
|
colKey?: UniqKeyProp;
|
|
241
241
|
/** 空值展示文字 */
|
|
242
|
-
emptyCellText?: string;
|
|
242
|
+
emptyCellText?: string | ((option: { row: DT; col: StkTableColumn<DT> }) => string);
|
|
243
243
|
/** 暂无数据兜底高度是否撑满 */
|
|
244
244
|
noDataFull?: boolean;
|
|
245
245
|
/** 是否展示暂无数据 */
|
|
@@ -258,7 +258,7 @@ const props = withDefaults(
|
|
|
258
258
|
* 给行附加className<br>
|
|
259
259
|
* FIXME: 是否需要优化,因为不传此prop会使表格行一直执行空函数,是否有影响
|
|
260
260
|
*/
|
|
261
|
-
rowClassName?: (row:
|
|
261
|
+
rowClassName?: (row: DT, i: number) => string;
|
|
262
262
|
/**
|
|
263
263
|
* 列宽是否可拖动<br>
|
|
264
264
|
* **不要设置**列minWidth,**必须**设置width<br>
|
|
@@ -446,6 +446,15 @@ const dataSourceCopy = shallowRef<DT[]>([...props.dataSource]);
|
|
|
446
446
|
/**高亮帧间隔
|
|
447
447
|
const highlightStepDuration = Highlight_Color_Change_Freq / 1000 + 's';*/
|
|
448
448
|
|
|
449
|
+
/** 空单元格占位字符 */
|
|
450
|
+
const getEmptyCellText = computed(() => {
|
|
451
|
+
if (typeof props.emptyCellText === 'string') {
|
|
452
|
+
return () => props.emptyCellText;
|
|
453
|
+
} else {
|
|
454
|
+
return (col: StkTableColumn<DT>, row: DT) => (props.emptyCellText as any)({ row, col });
|
|
455
|
+
}
|
|
456
|
+
});
|
|
457
|
+
|
|
449
458
|
/** rowKey缓存 */
|
|
450
459
|
const rowKeyGenStore = new WeakMap();
|
|
451
460
|
|
|
@@ -504,8 +513,9 @@ useKeyboardArrowScroll(tableContainer, {
|
|
|
504
513
|
});
|
|
505
514
|
|
|
506
515
|
/** 固定列处理 */
|
|
507
|
-
const {
|
|
516
|
+
const { fixedColClassMap, dealFixedColShadow, updateFixedShadow } = useFixedCol({
|
|
508
517
|
props,
|
|
518
|
+
colKeyGen,
|
|
509
519
|
tableContainer,
|
|
510
520
|
tableHeaderLast,
|
|
511
521
|
});
|
|
@@ -558,8 +568,8 @@ onMounted(() => {
|
|
|
558
568
|
/** 处理默认排序 */
|
|
559
569
|
function dealDefaultSorter() {
|
|
560
570
|
if (!props.sortConfig.defaultSort) return;
|
|
561
|
-
const { dataIndex, order } = props.sortConfig.defaultSort;
|
|
562
|
-
setSorter(dataIndex as string, order);
|
|
571
|
+
const { dataIndex, order, silent } = { silent: false, ...props.sortConfig.defaultSort };
|
|
572
|
+
setSorter(dataIndex as string, order, { force: false, silent });
|
|
563
573
|
}
|
|
564
574
|
|
|
565
575
|
/**
|
|
@@ -659,47 +669,45 @@ function colKeyGen(col: StkTableColumn<DT>) {
|
|
|
659
669
|
return typeof props.colKey === 'function' ? props.colKey(col) : (col as any)[props.colKey];
|
|
660
670
|
}
|
|
661
671
|
|
|
662
|
-
/**
|
|
663
|
-
|
|
664
|
-
const
|
|
665
|
-
const
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
672
|
+
/** 单元格样式 */
|
|
673
|
+
const cellStyleMap = computed(() => {
|
|
674
|
+
const thMap = new Map();
|
|
675
|
+
const tdMap = new Map();
|
|
676
|
+
tableHeaders.value.forEach((cols, depth) => {
|
|
677
|
+
cols.forEach(col => {
|
|
678
|
+
const colKey = colKeyGen(col);
|
|
679
|
+
const width = getColWidthStr(col);
|
|
680
|
+
const style: CSSProperties = {
|
|
681
|
+
width,
|
|
682
|
+
};
|
|
683
|
+
if (props.colResizable) {
|
|
684
|
+
style.minWidth = width;
|
|
685
|
+
style.maxWidth = width;
|
|
686
|
+
} else {
|
|
687
|
+
style.minWidth = getColWidthStr(col, 'minWidth') ?? width;
|
|
688
|
+
style.maxWidth = getColWidthStr(col, 'maxWidth') ?? width;
|
|
689
|
+
}
|
|
679
690
|
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
691
|
+
const thStyle = {
|
|
692
|
+
...style,
|
|
693
|
+
...getFixedStyle(TagType.TH, col, depth),
|
|
694
|
+
textAlign: col.headerAlign,
|
|
695
|
+
};
|
|
696
|
+
const tdStyle = {
|
|
697
|
+
...style,
|
|
698
|
+
...getFixedStyle(TagType.TD, col, depth),
|
|
699
|
+
textAlign: col.align,
|
|
700
|
+
};
|
|
701
|
+
|
|
702
|
+
thMap.set(colKey, thStyle);
|
|
703
|
+
tdMap.set(colKey, tdStyle);
|
|
704
|
+
});
|
|
705
|
+
});
|
|
706
|
+
return {
|
|
707
|
+
[TagType.TH]: thMap,
|
|
708
|
+
[TagType.TD]: tdMap,
|
|
692
709
|
};
|
|
693
|
-
|
|
694
|
-
// TH
|
|
695
|
-
style.textAlign = col.headerAlign;
|
|
696
|
-
} else if (tagType === 2) {
|
|
697
|
-
// TD
|
|
698
|
-
style.textAlign = col.align;
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
return style;
|
|
702
|
-
}
|
|
710
|
+
});
|
|
703
711
|
|
|
704
712
|
/** th title */
|
|
705
713
|
function getHeaderTitle(col: StkTableColumn<DT>): string {
|
|
@@ -859,8 +867,9 @@ function setCurrentRow(rowKey: string, option = { silent: false }) {
|
|
|
859
867
|
* @param option.sortOption 指定排序参数。同 StkTableColumn 中排序相关字段。建议从columns中find得到。
|
|
860
868
|
* @param option.sort 是否触发排序-默认true
|
|
861
869
|
* @param option.silent 是否禁止触发回调-默认true
|
|
870
|
+
* @param option.force 是否触发排序-默认true
|
|
862
871
|
*/
|
|
863
|
-
function setSorter(dataIndex: string, order: Order, option: { sortOption?: SortOption<DT>; silent?: boolean; sort?: boolean } = {}) {
|
|
872
|
+
function setSorter(dataIndex: string, order: Order, option: { sortOption?: SortOption<DT>; force?: boolean; silent?: boolean; sort?: boolean } = {}) {
|
|
864
873
|
const newOption = { silent: true, sortOption: null, sort: true, ...option };
|
|
865
874
|
sortCol.value = dataIndex;
|
|
866
875
|
sortOrderIndex.value = sortSwitchOrder.indexOf(order);
|
|
@@ -868,7 +877,7 @@ function setSorter(dataIndex: string, order: Order, option: { sortOption?: SortO
|
|
|
868
877
|
if (newOption.sort && dataSourceCopy.value?.length) {
|
|
869
878
|
// 如果表格有数据,则进行排序
|
|
870
879
|
const column = newOption.sortOption || tableHeaderLast.value.find(it => it.dataIndex === sortCol.value);
|
|
871
|
-
if (column) onColumnSort(column, false, { force: true, emit: !newOption.silent });
|
|
880
|
+
if (column) onColumnSort(column, false, { force: option.force ?? true, emit: !newOption.silent });
|
|
872
881
|
else console.warn('Can not find column by dataIndex:', sortCol.value);
|
|
873
882
|
}
|
|
874
883
|
return dataSourceCopy.value;
|
|
@@ -77,10 +77,15 @@ export type UniqKeyProp = UniqKey | UniqKeyFun;
|
|
|
77
77
|
export type SortConfig<T extends Record<string, any>> = {
|
|
78
78
|
/** 空值始终排在列表末尾 */
|
|
79
79
|
emptyToBottom?: boolean;
|
|
80
|
-
/**
|
|
80
|
+
/**
|
|
81
|
+
* 默认排序(1.初始化时触发 2.排序方向为null时触发)
|
|
82
|
+
* 类似onMounted时,调用setSorter点了下表头。
|
|
83
|
+
*/
|
|
81
84
|
defaultSort?: {
|
|
82
85
|
dataIndex: keyof T;
|
|
83
86
|
order: Order;
|
|
87
|
+
/** 是否禁止触发sort-change事件。默认false,表示触发事件。 */
|
|
88
|
+
silent?: boolean;
|
|
84
89
|
};
|
|
85
90
|
/**
|
|
86
91
|
* string排序是否使用 String.prototype.localCompare
|
|
@@ -88,3 +93,9 @@ export type SortConfig<T extends Record<string, any>> = {
|
|
|
88
93
|
*/
|
|
89
94
|
stringLocaleCompare?: boolean;
|
|
90
95
|
};
|
|
96
|
+
|
|
97
|
+
/** th td类型 */
|
|
98
|
+
export const enum TagType {
|
|
99
|
+
TH,
|
|
100
|
+
TD,
|
|
101
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { ref, Ref } from 'vue';
|
|
1
|
+
import { computed, ref, Ref, shallowRef } from 'vue';
|
|
2
2
|
import { StkTableColumn } from './types';
|
|
3
3
|
|
|
4
4
|
type Params<T extends Record<string, any>> = {
|
|
5
5
|
props: any;
|
|
6
|
+
colKeyGen: (col: StkTableColumn<T>) => string;
|
|
6
7
|
tableHeaderLast: Ref<StkTableColumn<T>[]>;
|
|
7
8
|
tableContainer: Ref<HTMLDivElement | undefined>;
|
|
8
9
|
};
|
|
@@ -11,7 +12,7 @@ type Params<T extends Record<string, any>> = {
|
|
|
11
12
|
* 固定列处理
|
|
12
13
|
* @returns
|
|
13
14
|
*/
|
|
14
|
-
export function useFixedCol<DT extends Record<string, any>>({ props, tableHeaderLast, tableContainer }: Params<DT>) {
|
|
15
|
+
export function useFixedCol<DT extends Record<string, any>>({ props, colKeyGen, tableHeaderLast, tableContainer }: Params<DT>) {
|
|
15
16
|
/** 固定列阴影 */
|
|
16
17
|
const fixedShadow = ref<{
|
|
17
18
|
/** 是否展示左侧固定列阴影 */
|
|
@@ -23,12 +24,31 @@ export function useFixedCol<DT extends Record<string, any>>({ props, tableHeader
|
|
|
23
24
|
showR: false,
|
|
24
25
|
});
|
|
25
26
|
/** 保存需要出现阴影的列 */
|
|
26
|
-
|
|
27
|
+
const fixedShadowCols = shallowRef<StkTableColumn<DT>[]>([]);
|
|
28
|
+
|
|
29
|
+
const fixedColClassMap = computed(() => {
|
|
30
|
+
const colMap = new Map();
|
|
31
|
+
props.columns.forEach((col: any) => {
|
|
32
|
+
const { showR, showL } = fixedShadow.value;
|
|
33
|
+
const showShadow =
|
|
34
|
+
props.fixedColShadow &&
|
|
35
|
+
col.fixed &&
|
|
36
|
+
((showL && col.fixed === 'left') || (showR && col.fixed === 'right')) &&
|
|
37
|
+
fixedShadowCols.value.includes(col);
|
|
38
|
+
const classObj = {
|
|
39
|
+
'fixed-cell': col.fixed,
|
|
40
|
+
['fixed-cell--' + col.fixed]: col.fixed,
|
|
41
|
+
'fixed-cell--shadow': showShadow,
|
|
42
|
+
};
|
|
43
|
+
colMap.set(colKeyGen(col), classObj);
|
|
44
|
+
});
|
|
45
|
+
return colMap;
|
|
46
|
+
});
|
|
27
47
|
|
|
28
48
|
/** 处理固定列阴影 */
|
|
29
49
|
function dealFixedColShadow() {
|
|
30
50
|
if (!props.fixedColShadow) return;
|
|
31
|
-
fixedShadowCols = [];
|
|
51
|
+
fixedShadowCols.value = [];
|
|
32
52
|
// 找到最右边的固定列 findLast
|
|
33
53
|
let lastLeftCol = null;
|
|
34
54
|
for (let i = tableHeaderLast.value.length - 1; i >= 0; i--) {
|
|
@@ -42,7 +62,7 @@ export function useFixedCol<DT extends Record<string, any>>({ props, tableHeader
|
|
|
42
62
|
let node: any = { __PARENT__: lastLeftCol };
|
|
43
63
|
while ((node = node.__PARENT__)) {
|
|
44
64
|
if (node.fixed) {
|
|
45
|
-
fixedShadowCols.push(node);
|
|
65
|
+
fixedShadowCols.value.push(node);
|
|
46
66
|
}
|
|
47
67
|
}
|
|
48
68
|
|
|
@@ -51,27 +71,11 @@ export function useFixedCol<DT extends Record<string, any>>({ props, tableHeader
|
|
|
51
71
|
node = { __PARENT__: lastRightCol };
|
|
52
72
|
while ((node = node.__PARENT__)) {
|
|
53
73
|
if (node.fixed) {
|
|
54
|
-
fixedShadowCols.push(node);
|
|
74
|
+
fixedShadowCols.value.push(node);
|
|
55
75
|
}
|
|
56
76
|
}
|
|
57
77
|
}
|
|
58
78
|
|
|
59
|
-
/** 固定列class */
|
|
60
|
-
function getFixedColClass(col: StkTableColumn<DT>): Record<string, boolean> {
|
|
61
|
-
const { showR, showL } = fixedShadow.value;
|
|
62
|
-
const showShadow =
|
|
63
|
-
props.fixedColShadow &&
|
|
64
|
-
col.fixed &&
|
|
65
|
-
((showL && col.fixed === 'left') || (showR && col.fixed === 'right')) &&
|
|
66
|
-
fixedShadowCols.includes(col);
|
|
67
|
-
const classObj = {
|
|
68
|
-
'fixed-cell': col.fixed,
|
|
69
|
-
['fixed-cell--' + col.fixed]: col.fixed,
|
|
70
|
-
'fixed-cell--shadow': showShadow,
|
|
71
|
-
};
|
|
72
|
-
return classObj;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
79
|
/** 滚动条变化时,更新需要展示阴影的列 */
|
|
76
80
|
function updateFixedShadow() {
|
|
77
81
|
if (!props.fixedColShadow) return;
|
|
@@ -82,7 +86,7 @@ export function useFixedCol<DT extends Record<string, any>>({ props, tableHeader
|
|
|
82
86
|
|
|
83
87
|
return {
|
|
84
88
|
/** 固定列class */
|
|
85
|
-
|
|
89
|
+
fixedColClassMap,
|
|
86
90
|
/** 处理固定列阴影 */
|
|
87
91
|
dealFixedColShadow,
|
|
88
92
|
/** 滚动条变化时,更新需要展示阴影的列 */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CSSProperties, Ref, computed } from 'vue';
|
|
2
2
|
import { Is_Legacy_Mode } from './const';
|
|
3
|
-
import { StkTableColumn } from './types';
|
|
3
|
+
import { StkTableColumn, TagType } from './types';
|
|
4
4
|
import { VirtualScrollStore, VirtualScrollXStore } from './useVirtualScroll';
|
|
5
5
|
import { getColWidth } from './utils';
|
|
6
6
|
|
|
@@ -64,24 +64,25 @@ export function useFixedStyle<DT extends Record<string, any>>({
|
|
|
64
64
|
|
|
65
65
|
return { refStore, colKeyStore };
|
|
66
66
|
});
|
|
67
|
+
|
|
67
68
|
/**
|
|
68
69
|
* 固定列的style
|
|
69
70
|
* @param tagType 1-th 2-td
|
|
70
71
|
* @param col
|
|
71
72
|
* @param depth 深度。tagType = 1时使用
|
|
72
73
|
*/
|
|
73
|
-
function getFixedStyle(tagType:
|
|
74
|
+
function getFixedStyle(tagType: TagType, col: StkTableColumn<DT>, depth = 0): CSSProperties {
|
|
74
75
|
const { fixed } = col;
|
|
75
76
|
const isFixedLeft = fixed === 'left';
|
|
76
77
|
const style: CSSProperties = {};
|
|
77
78
|
const { colKeyStore, refStore } = fixedColumnsPositionStore.value;
|
|
78
|
-
|
|
79
|
+
|
|
79
80
|
if (Is_Legacy_Mode) {
|
|
80
81
|
style.position = 'relative';
|
|
81
82
|
} else {
|
|
82
83
|
style.position = 'sticky';
|
|
83
84
|
}
|
|
84
|
-
if (tagType ===
|
|
85
|
+
if (tagType === TagType.TH) {
|
|
85
86
|
// TH
|
|
86
87
|
if (Is_Legacy_Mode) {
|
|
87
88
|
style.top = virtualScroll.value.scrollTop + depth * props.rowHeight + 'px';
|
|
@@ -90,6 +91,7 @@ export function useFixedStyle<DT extends Record<string, any>>({
|
|
|
90
91
|
}
|
|
91
92
|
style.zIndex = isFixedLeft ? '5' : '4'; // 保证固定列高于其他单元格
|
|
92
93
|
} else {
|
|
94
|
+
// TD
|
|
93
95
|
style.zIndex = isFixedLeft ? '3' : '2';
|
|
94
96
|
}
|
|
95
97
|
|
|
@@ -76,6 +76,9 @@ export function useHighlight({ props, tableContainer }: Params) {
|
|
|
76
76
|
}
|
|
77
77
|
});
|
|
78
78
|
|
|
79
|
+
// $*$ 兼容vue2响应
|
|
80
|
+
highlightRowStore.value = { ...highlightRowStore.value };
|
|
81
|
+
|
|
79
82
|
if (highlightDimRowKeys.size > 0) {
|
|
80
83
|
// 还有高亮的行,则下一次循环
|
|
81
84
|
recursion();
|
|
@@ -111,16 +114,17 @@ export function useHighlight({ props, tableContainer }: Params) {
|
|
|
111
114
|
/**
|
|
112
115
|
* 高亮一行
|
|
113
116
|
* @param rowKeyValues
|
|
117
|
+
* @param option.useCss 虚拟滚动时,高亮由js控制。如果仍想使用css 关键帧控制,则配置此项
|
|
114
118
|
*/
|
|
115
|
-
function setHighlightDimRow(rowKeyValues: UniqKey[]) {
|
|
119
|
+
function setHighlightDimRow(rowKeyValues: UniqKey[], option: { useCss?: boolean } = {}) {
|
|
116
120
|
if (!Array.isArray(rowKeyValues)) rowKeyValues = [rowKeyValues];
|
|
117
|
-
if (props.virtual) {
|
|
121
|
+
if (props.virtual && !option.useCss) {
|
|
118
122
|
// --------虚拟滚动用js计算颜色渐变的高亮方案
|
|
119
123
|
const nowTs = Date.now(); // 重置渐变进度
|
|
120
124
|
for (let i = 0; i < rowKeyValues.length; i++) {
|
|
121
125
|
const rowKeyValue = rowKeyValues[i];
|
|
122
126
|
highlightRowStore.value[rowKeyValue] = {
|
|
123
|
-
bgc:
|
|
127
|
+
bgc: highlightFrom.value,
|
|
124
128
|
bgc_progress: 0,
|
|
125
129
|
bgc_progress_ms: nowTs,
|
|
126
130
|
};
|