stk-table-vue 0.0.1-beta.5 → 0.0.1-beta.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 +6 -29
- package/lib/src/StkTable/StkTable.vue.d.ts +11 -8
- package/lib/src/StkTable/types/index.d.ts +8 -3
- package/lib/src/StkTable/useAutoResize.d.ts +15 -0
- package/lib/src/StkTable/useKeyboardArrowScroll.d.ts +14 -0
- package/lib/src/StkTable/useVirtualScroll.d.ts +32 -0
- package/lib/stk-table-vue.js +144 -22
- package/lib/style.css +238 -227
- package/lib/test/utils/DragResize.d.ts +28 -0
- package/lib/test/utils/h.d.ts +10 -0
- package/package.json +59 -59
- package/src/StkTable/StkTable.vue +84 -64
- package/src/StkTable/types/index.ts +6 -3
- package/src/StkTable/useAutoResize.ts +38 -5
- package/src/StkTable/useKeyboardArrowScroll.ts +66 -0
- package/src/StkTable/useVirtualScroll.ts +61 -26
- package/src/StkTable/utils.ts +1 -0
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
# StkTable
|
|
1
|
+
# StkTable (Sticky Table)
|
|
2
2
|
|
|
3
3
|
Vue3 简易虚拟滚动表格。用于实时数据展示,新数据行高亮渐暗动效。
|
|
4
|
-
js体积(
|
|
4
|
+
js体积(未压缩41kb)
|
|
5
5
|
|
|
6
6
|
## 功能
|
|
7
7
|
* [x] 高亮行,单元格。
|
|
@@ -11,7 +11,8 @@ js体积(38kb)
|
|
|
11
11
|
* [x] 表头列宽拖动。
|
|
12
12
|
* [x] 多级表头。(不支持横向虚拟滚动)
|
|
13
13
|
* [x] 支持table-layout: fixed 配置。
|
|
14
|
-
* []
|
|
14
|
+
* [x] 鼠标悬浮在表格上,键盘上下左右滚动虚拟表格
|
|
15
|
+
* [] 列固定阴影
|
|
15
16
|
|
|
16
17
|
## Usage
|
|
17
18
|
> npm install stk-table-vue
|
|
@@ -36,80 +37,57 @@ const stkTable = ref<InstanceType<typeof StkTable>>();
|
|
|
36
37
|
```ts
|
|
37
38
|
export type StkProps = Partial<{
|
|
38
39
|
width: string;
|
|
39
|
-
|
|
40
40
|
/** 最小表格宽度 */
|
|
41
41
|
minWidth: string;
|
|
42
|
-
|
|
43
42
|
/** 表格最大宽度*/
|
|
44
43
|
maxWidth: string;
|
|
45
|
-
|
|
46
44
|
/** 是否使用 table-layout:fixed */
|
|
47
45
|
fixedMode: boolean;
|
|
48
|
-
|
|
49
46
|
/** 是否隐藏表头 */
|
|
50
47
|
headless: boolean;
|
|
51
|
-
|
|
52
48
|
/** 主题,亮、暗 */
|
|
53
49
|
theme: 'light' | 'dark';
|
|
54
|
-
|
|
55
50
|
/** 虚拟滚动 */
|
|
56
51
|
virtual: boolean;
|
|
57
|
-
|
|
58
52
|
/** x轴虚拟滚动 */
|
|
59
53
|
virtualX: boolean;
|
|
60
|
-
|
|
61
54
|
/** 表格列配置 */
|
|
62
55
|
columns: StkTableColumn<any>[];
|
|
63
|
-
|
|
64
56
|
/** 表格数据源 */
|
|
65
57
|
dataSource: any[];
|
|
66
|
-
|
|
67
58
|
/** 行唯一键 */
|
|
68
59
|
rowKey: UniqKey;
|
|
69
|
-
|
|
70
60
|
/** 列唯一键 */
|
|
71
61
|
colKey: UniqKey;
|
|
72
|
-
|
|
73
62
|
/** 空值展示文字 */
|
|
74
63
|
emptyCellText: string;
|
|
75
|
-
|
|
76
64
|
/** 暂无数据兜底高度是否撑满 */
|
|
77
65
|
noDataFull: boolean;
|
|
78
|
-
|
|
79
66
|
/** 是否展示暂无数据 */
|
|
80
67
|
showNoData: boolean;
|
|
81
|
-
|
|
82
68
|
/** 是否服务端排序,true则不排序数据 */
|
|
83
69
|
sortRemote: boolean;
|
|
84
|
-
|
|
85
70
|
/** 表头是否溢出展示... */
|
|
86
71
|
showHeaderOverflow: boolean;
|
|
87
|
-
|
|
88
72
|
/** 表体溢出是否展示... */
|
|
89
73
|
showOverflow: boolean;
|
|
90
|
-
|
|
91
74
|
/** 是否增加行hover class */
|
|
92
75
|
showTrHoverClass: boolean;
|
|
93
|
-
|
|
94
76
|
/** 表头是否可拖动 */
|
|
95
77
|
headerDrag: boolean;
|
|
96
|
-
|
|
97
78
|
/**
|
|
98
79
|
* 给行附加className<br>
|
|
99
80
|
* FIXME: 是否需要优化,因为不传此prop会使表格行一直执行空函数,是否有影响
|
|
100
81
|
*/
|
|
101
82
|
rowClassName: (row: any, i: number) => string;
|
|
102
|
-
|
|
103
83
|
/**
|
|
104
84
|
* 列宽是否可拖动<br>
|
|
105
85
|
* **不要设置**列minWidth,**必须**设置width<br>
|
|
106
86
|
* 列宽拖动时,每一列都必须要有width,且minWidth/maxWidth不生效。table width会变为"fit-content"。
|
|
107
87
|
*/
|
|
108
88
|
colResizable: boolean;
|
|
109
|
-
|
|
110
89
|
/** 可拖动至最小的列宽 */
|
|
111
90
|
colMinWidth: number;
|
|
112
|
-
|
|
113
91
|
/**
|
|
114
92
|
* 单元格分割线。
|
|
115
93
|
* 默认横竖都有
|
|
@@ -118,7 +96,6 @@ export type StkProps = Partial<{
|
|
|
118
96
|
* "body-v" - 仅表体展示竖线
|
|
119
97
|
*/
|
|
120
98
|
bordered: boolean | 'h' | 'v' | 'body-v';
|
|
121
|
-
|
|
122
99
|
/** 自动重新计算虚拟滚动高度宽度。默认true */
|
|
123
100
|
autoResize: boolean;
|
|
124
101
|
}>;
|
|
@@ -126,7 +103,7 @@ export type StkProps = Partial<{
|
|
|
126
103
|
|
|
127
104
|
### StkTableColumn
|
|
128
105
|
``` ts
|
|
129
|
-
type Sorter = boolean |
|
|
106
|
+
type Sorter<T> = boolean | ((data: T[], option: { order: Order; column: any }) => T[]);
|
|
130
107
|
/** 表格列配置 */
|
|
131
108
|
export type StkTableColumn<T extends Record<string, any>> = {
|
|
132
109
|
/** 取值id */
|
|
@@ -138,7 +115,7 @@ export type StkTableColumn<T extends Record<string, any>> = {
|
|
|
138
115
|
/** 表头内容对齐方式 */
|
|
139
116
|
headerAlign?: 'right' | 'left' | 'center';
|
|
140
117
|
/** 筛选 */
|
|
141
|
-
sorter?: Sorter
|
|
118
|
+
sorter?: Sorter<T>;
|
|
142
119
|
/** 列宽。横向虚拟滚动时必须设置。 */
|
|
143
120
|
width?: string;
|
|
144
121
|
/** 最小列宽。非x虚拟滚动生效。 */
|
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
import { SortOption, StkTableColumn } from './types/index';
|
|
2
|
-
/**
|
|
3
|
-
* 初始化虚拟滚动参数
|
|
4
|
-
* @param {number} [height] 虚拟滚动的高度
|
|
5
|
-
*/
|
|
6
|
-
declare function initVirtualScroll(height?: number): void;
|
|
7
2
|
/**
|
|
8
3
|
* 选中一行,
|
|
9
4
|
* @param {string} rowKey
|
|
@@ -40,10 +35,11 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
|
|
|
40
35
|
minWidth: string;
|
|
41
36
|
maxWidth: string;
|
|
42
37
|
fixedMode: boolean;
|
|
43
|
-
headless: boolean;
|
|
38
|
+
headless: boolean;
|
|
44
39
|
theme: "light" | "dark";
|
|
45
40
|
virtual: boolean;
|
|
46
41
|
virtualX: boolean;
|
|
42
|
+
/** 排序切换顺序 */
|
|
47
43
|
columns: StkTableColumn<any>[];
|
|
48
44
|
dataSource: any[];
|
|
49
45
|
rowKey: import("./types/index").UniqKey;
|
|
@@ -60,6 +56,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
|
|
|
60
56
|
colResizable: boolean;
|
|
61
57
|
colMinWidth: number;
|
|
62
58
|
bordered: boolean | "h" | "v" | "body-v";
|
|
59
|
+
autoResize: boolean;
|
|
63
60
|
}>>, {
|
|
64
61
|
width: string;
|
|
65
62
|
fixedMode: boolean;
|
|
@@ -85,13 +82,15 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
|
|
|
85
82
|
colResizable: boolean;
|
|
86
83
|
colMinWidth: number;
|
|
87
84
|
bordered: boolean;
|
|
85
|
+
autoResize: boolean;
|
|
88
86
|
}>, {
|
|
89
|
-
initVirtualScroll:
|
|
87
|
+
initVirtualScroll: (height?: number | undefined) => void;
|
|
90
88
|
initVirtualScrollX: () => void;
|
|
91
89
|
initVirtualScrollY: (height?: number | undefined) => void;
|
|
92
90
|
setCurrentRow: typeof setCurrentRow;
|
|
93
91
|
setHighlightDimCell: (rowKeyValue: string, dataIndex: string) => void;
|
|
94
92
|
setHighlightDimRow: (rowKeyValues: (string | number)[]) => void;
|
|
93
|
+
sortCol: import("vue").Ref<string | null | undefined>;
|
|
95
94
|
setSorter: typeof setSorter;
|
|
96
95
|
resetSorter: typeof resetSorter;
|
|
97
96
|
scrollTo: typeof scrollTo;
|
|
@@ -115,10 +114,11 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
|
|
|
115
114
|
minWidth: string;
|
|
116
115
|
maxWidth: string;
|
|
117
116
|
fixedMode: boolean;
|
|
118
|
-
headless: boolean;
|
|
117
|
+
headless: boolean;
|
|
119
118
|
theme: "light" | "dark";
|
|
120
119
|
virtual: boolean;
|
|
121
120
|
virtualX: boolean;
|
|
121
|
+
/** 排序切换顺序 */
|
|
122
122
|
columns: StkTableColumn<any>[];
|
|
123
123
|
dataSource: any[];
|
|
124
124
|
rowKey: import("./types/index").UniqKey;
|
|
@@ -135,6 +135,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
|
|
|
135
135
|
colResizable: boolean;
|
|
136
136
|
colMinWidth: number;
|
|
137
137
|
bordered: boolean | "h" | "v" | "body-v";
|
|
138
|
+
autoResize: boolean;
|
|
138
139
|
}>>, {
|
|
139
140
|
width: string;
|
|
140
141
|
fixedMode: boolean;
|
|
@@ -160,6 +161,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
|
|
|
160
161
|
colResizable: boolean;
|
|
161
162
|
colMinWidth: number;
|
|
162
163
|
bordered: boolean;
|
|
164
|
+
autoResize: boolean;
|
|
163
165
|
}>>> & {
|
|
164
166
|
onScroll?: ((...args: any[]) => any) | undefined;
|
|
165
167
|
"onTh-drag-start"?: ((...args: any[]) => any) | undefined;
|
|
@@ -199,6 +201,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
|
|
|
199
201
|
colResizable: boolean;
|
|
200
202
|
colMinWidth: number;
|
|
201
203
|
bordered: boolean | "h" | "v" | "body-v";
|
|
204
|
+
autoResize: boolean;
|
|
202
205
|
}, {}>, {
|
|
203
206
|
tableHeader?(_: {
|
|
204
207
|
column: StkTableColumn<any>;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Component, VNode } from 'vue';
|
|
2
2
|
/** 排序方式,asc-正序,desc-倒序,null-默认顺序 */
|
|
3
3
|
export type Order = null | 'asc' | 'desc';
|
|
4
|
-
type Sorter = boolean | ((data:
|
|
4
|
+
type Sorter<T> = boolean | ((data: T[], option: {
|
|
5
5
|
order: Order;
|
|
6
6
|
column: any;
|
|
7
|
-
}) =>
|
|
7
|
+
}) => T[]);
|
|
8
8
|
export type CustomCellFunc<T extends Record<string, any>> = (props: {
|
|
9
9
|
row: T;
|
|
10
10
|
col: StkTableColumn<T>;
|
|
@@ -24,7 +24,7 @@ export type StkTableColumn<T extends Record<string, any>> = {
|
|
|
24
24
|
/** 表头内容对齐方式 */
|
|
25
25
|
headerAlign?: 'right' | 'left' | 'center';
|
|
26
26
|
/** 筛选 */
|
|
27
|
-
sorter?: Sorter
|
|
27
|
+
sorter?: Sorter<T>;
|
|
28
28
|
/** 列宽。横向虚拟滚动时必须设置。 */
|
|
29
29
|
width?: string;
|
|
30
30
|
/** 最小列宽。非x虚拟滚动生效。 */
|
|
@@ -118,5 +118,10 @@ export type StkProps = Partial<{
|
|
|
118
118
|
* "body-v" - 仅表体展示竖线
|
|
119
119
|
*/
|
|
120
120
|
bordered: boolean | 'h' | 'v' | 'body-v';
|
|
121
|
+
/**
|
|
122
|
+
* 自动重新计算虚拟滚动高度宽度。默认true
|
|
123
|
+
* [非响应式]
|
|
124
|
+
*/
|
|
125
|
+
autoResize: boolean;
|
|
121
126
|
}>;
|
|
122
127
|
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Ref } from 'vue';
|
|
2
|
+
type Options = {
|
|
3
|
+
tableContainer: Ref<HTMLElement | undefined>;
|
|
4
|
+
initVirtualScroll: () => void;
|
|
5
|
+
scrollTo: () => void;
|
|
6
|
+
props: any;
|
|
7
|
+
/** 防抖延时 */
|
|
8
|
+
debounceMs: number;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* 窗口变化自动重置虚拟滚动
|
|
12
|
+
* @param param0
|
|
13
|
+
*/
|
|
14
|
+
export declare function useAutoResize({ tableContainer, initVirtualScroll, scrollTo, props, debounceMs }: Options): void;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Ref } from 'vue';
|
|
2
|
+
import { VirtualScrollStore, VirtualScrollXStore } from './useVirtualScroll';
|
|
3
|
+
type Options = {
|
|
4
|
+
scrollTo: (x: number | null, y: number | null) => void;
|
|
5
|
+
virtualScroll: Ref<VirtualScrollStore>;
|
|
6
|
+
virtualScrollX: Ref<VirtualScrollXStore>;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* 按下键盘箭头滚动。只有悬浮在表体上才能生效键盘。
|
|
10
|
+
*
|
|
11
|
+
* 在低版本浏览器中,虚拟滚动时,使用键盘滚动,等选中的行消失在视口外时,滚动会失效。
|
|
12
|
+
*/
|
|
13
|
+
export declare function useKeyboardArrowScroll(targetElement: Ref<HTMLElement | undefined>, { scrollTo, virtualScroll, virtualScrollX }: Options): void;
|
|
14
|
+
export {};
|
|
@@ -6,6 +6,37 @@ type Option = {
|
|
|
6
6
|
dataSourceCopy: ShallowRef<any[]>;
|
|
7
7
|
tableHeaderLast: Ref<StkTableColumn<any>[]>;
|
|
8
8
|
};
|
|
9
|
+
/** 暂存纵向虚拟滚动的数据 */
|
|
10
|
+
export type VirtualScrollStore = {
|
|
11
|
+
/** 容器高度 */
|
|
12
|
+
containerHeight: number;
|
|
13
|
+
/** 数组开始位置 */
|
|
14
|
+
startIndex: number;
|
|
15
|
+
/** 行高 */
|
|
16
|
+
rowHeight: number;
|
|
17
|
+
/** 表格定位上边距 */
|
|
18
|
+
offsetTop: number;
|
|
19
|
+
/** 纵向滚动条位置,用于判断是横向滚动还是纵向 */
|
|
20
|
+
scrollTop: number;
|
|
21
|
+
};
|
|
22
|
+
/** 暂存横向虚拟滚动的数据 */
|
|
23
|
+
export type VirtualScrollXStore = {
|
|
24
|
+
/** 容器宽度 */
|
|
25
|
+
containerWidth: number;
|
|
26
|
+
/** 开始位置 */
|
|
27
|
+
startIndex: number;
|
|
28
|
+
/** 结束始位置 */
|
|
29
|
+
endIndex: number;
|
|
30
|
+
/** 表格定位左边距 */
|
|
31
|
+
offsetLeft: number;
|
|
32
|
+
/** 横向滚动位置,用于判断是横向滚动还是纵向 */
|
|
33
|
+
scrollLeft: number;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* 虚拟滚动
|
|
37
|
+
* @param param0
|
|
38
|
+
* @returns
|
|
39
|
+
*/
|
|
9
40
|
export declare function useVirtualScroll({ tableContainer, props, dataSourceCopy, tableHeaderLast }: Option): {
|
|
10
41
|
virtualScroll: Ref<{
|
|
11
42
|
containerHeight: number;
|
|
@@ -27,6 +58,7 @@ export declare function useVirtualScroll({ tableContainer, props, dataSourceCopy
|
|
|
27
58
|
virtualX_on: import("vue").ComputedRef<any>;
|
|
28
59
|
virtualX_columnPart: import("vue").ComputedRef<StkTableColumn<any>[]>;
|
|
29
60
|
virtualX_offsetRight: import("vue").ComputedRef<number>;
|
|
61
|
+
initVirtualScroll: (height?: number) => void;
|
|
30
62
|
initVirtualScrollY: (height?: number) => void;
|
|
31
63
|
initVirtualScrollX: () => void;
|
|
32
64
|
updateVirtualScrollY: (sTop?: number) => void;
|
package/lib/stk-table-vue.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { onMounted, onBeforeUnmount, watch, ref, computed, defineComponent, shallowRef, 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;
|
|
@@ -19,6 +19,54 @@ try {
|
|
|
19
19
|
console.error("Cannot get Chrome version", e);
|
|
20
20
|
}
|
|
21
21
|
const Is_Legacy_Mode = _chromeVersion < 56;
|
|
22
|
+
function useAutoResize({ tableContainer, initVirtualScroll, scrollTo, props, debounceMs }) {
|
|
23
|
+
let resizeObserver = null;
|
|
24
|
+
onMounted(() => {
|
|
25
|
+
initResizeObserver();
|
|
26
|
+
});
|
|
27
|
+
onBeforeUnmount(() => {
|
|
28
|
+
removeResizeObserver();
|
|
29
|
+
});
|
|
30
|
+
function initResizeObserver() {
|
|
31
|
+
if (window.ResizeObserver) {
|
|
32
|
+
if (!tableContainer.value) {
|
|
33
|
+
const watchDom = watch(
|
|
34
|
+
() => tableContainer,
|
|
35
|
+
() => {
|
|
36
|
+
initResizeObserver();
|
|
37
|
+
watchDom();
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
resizeObserver = new ResizeObserver(resizeCallback);
|
|
43
|
+
resizeObserver.observe(tableContainer.value);
|
|
44
|
+
} else {
|
|
45
|
+
window.addEventListener("resize", resizeCallback);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function removeResizeObserver() {
|
|
49
|
+
if (resizeObserver) {
|
|
50
|
+
resizeObserver.disconnect();
|
|
51
|
+
resizeObserver = null;
|
|
52
|
+
} else {
|
|
53
|
+
window.removeEventListener("resize", resizeCallback);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
let debounceTime = 0;
|
|
57
|
+
function resizeCallback() {
|
|
58
|
+
if (debounceTime) {
|
|
59
|
+
window.clearTimeout(debounceTime);
|
|
60
|
+
}
|
|
61
|
+
debounceTime = window.setTimeout(() => {
|
|
62
|
+
if (props.autoResize) {
|
|
63
|
+
scrollTo();
|
|
64
|
+
initVirtualScroll();
|
|
65
|
+
}
|
|
66
|
+
debounceTime = 0;
|
|
67
|
+
}, debounceMs);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
22
70
|
function useColResize({ tableContainer, tableHeaderLast, colResizeIndicator, props, emit, colKeyGen }) {
|
|
23
71
|
const isColResizing = ref(false);
|
|
24
72
|
let colResizeState = {
|
|
@@ -232,6 +280,52 @@ function useHighlight({ props, tableContainer, rowKeyGen }) {
|
|
|
232
280
|
setHighlightDimCell
|
|
233
281
|
};
|
|
234
282
|
}
|
|
283
|
+
const ARROW_CODES = ["ArrowUp", "ArrowRight", "ArrowDown", "ArrowLeft"];
|
|
284
|
+
function useKeyboardArrowScroll(targetElement, { scrollTo, virtualScroll, virtualScrollX }) {
|
|
285
|
+
let isMouseOver = false;
|
|
286
|
+
onMounted(() => {
|
|
287
|
+
var _a, _b, _c;
|
|
288
|
+
window.addEventListener("keydown", handleKeydown);
|
|
289
|
+
(_a = targetElement.value) == null ? void 0 : _a.addEventListener("mouseenter", handleMouseEnter);
|
|
290
|
+
(_b = targetElement.value) == null ? void 0 : _b.addEventListener("mouseleave", handleMouseLeave);
|
|
291
|
+
(_c = targetElement.value) == null ? void 0 : _c.addEventListener("mousedown", handleMouseDown);
|
|
292
|
+
});
|
|
293
|
+
onBeforeUnmount(() => {
|
|
294
|
+
var _a, _b, _c;
|
|
295
|
+
window.removeEventListener("keydown", handleKeydown);
|
|
296
|
+
(_a = targetElement.value) == null ? void 0 : _a.removeEventListener("mouseenter", handleMouseEnter);
|
|
297
|
+
(_b = targetElement.value) == null ? void 0 : _b.removeEventListener("mouseleave", handleMouseLeave);
|
|
298
|
+
(_c = targetElement.value) == null ? void 0 : _c.removeEventListener("mousedown", handleMouseDown);
|
|
299
|
+
});
|
|
300
|
+
function handleKeydown(e) {
|
|
301
|
+
if (!ARROW_CODES.includes(e.code))
|
|
302
|
+
return;
|
|
303
|
+
if (!isMouseOver)
|
|
304
|
+
return;
|
|
305
|
+
e.preventDefault();
|
|
306
|
+
const { scrollTop, rowHeight } = virtualScroll.value;
|
|
307
|
+
const { scrollLeft } = virtualScrollX.value;
|
|
308
|
+
if (e.code === ARROW_CODES[0]) {
|
|
309
|
+
scrollTo(scrollTop - rowHeight, null);
|
|
310
|
+
} else if (e.code === ARROW_CODES[1]) {
|
|
311
|
+
scrollTo(null, scrollLeft + rowHeight);
|
|
312
|
+
} else if (e.code === ARROW_CODES[2]) {
|
|
313
|
+
scrollTo(scrollTop + rowHeight, null);
|
|
314
|
+
} else if (e.code === ARROW_CODES[3]) {
|
|
315
|
+
scrollTo(null, scrollLeft - rowHeight);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
function handleMouseEnter() {
|
|
319
|
+
isMouseOver = true;
|
|
320
|
+
}
|
|
321
|
+
function handleMouseLeave() {
|
|
322
|
+
isMouseOver = false;
|
|
323
|
+
}
|
|
324
|
+
function handleMouseDown() {
|
|
325
|
+
if (!isMouseOver)
|
|
326
|
+
isMouseOver = true;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
235
329
|
function useThDrag({ emit }) {
|
|
236
330
|
let dragStartKey = void 0;
|
|
237
331
|
function onThDragStart(e) {
|
|
@@ -263,12 +357,9 @@ function useVirtualScroll({ tableContainer, props, dataSourceCopy, tableHeaderLa
|
|
|
263
357
|
const virtualScroll = ref({
|
|
264
358
|
containerHeight: 0,
|
|
265
359
|
startIndex: 0,
|
|
266
|
-
// 数组开始位置
|
|
267
360
|
rowHeight: 28,
|
|
268
361
|
offsetTop: 0,
|
|
269
|
-
// 表格定位上边距
|
|
270
362
|
scrollTop: 0
|
|
271
|
-
// 纵向滚动条位置,用于判断是横向滚动还是纵向
|
|
272
363
|
});
|
|
273
364
|
const virtualScrollX = ref({
|
|
274
365
|
containerWidth: 0,
|
|
@@ -276,7 +367,6 @@ function useVirtualScroll({ tableContainer, props, dataSourceCopy, tableHeaderLa
|
|
|
276
367
|
endIndex: 0,
|
|
277
368
|
offsetLeft: 0,
|
|
278
369
|
scrollLeft: 0
|
|
279
|
-
// 横向滚动位置,用于判断是横向滚动还是纵向
|
|
280
370
|
});
|
|
281
371
|
const virtual_on = computed(() => {
|
|
282
372
|
return props.virtual && dataSourceCopy.value.length > virtual_pageSize.value * 2;
|
|
@@ -327,18 +417,26 @@ function useVirtualScroll({ tableContainer, props, dataSourceCopy, tableHeaderLa
|
|
|
327
417
|
return width;
|
|
328
418
|
});
|
|
329
419
|
function initVirtualScrollY(height) {
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
420
|
+
if (!virtual_on.value)
|
|
421
|
+
return;
|
|
422
|
+
const { offsetHeight, scrollTop } = tableContainer.value || {};
|
|
423
|
+
if (typeof height === "number") {
|
|
424
|
+
virtualScroll.value.containerHeight = height;
|
|
425
|
+
} else {
|
|
426
|
+
virtualScroll.value.containerHeight = offsetHeight || Default_Table_Height;
|
|
334
427
|
}
|
|
428
|
+
updateVirtualScrollY(scrollTop);
|
|
335
429
|
}
|
|
336
430
|
function initVirtualScrollX() {
|
|
337
|
-
if (props.virtualX)
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
431
|
+
if (!props.virtualX)
|
|
432
|
+
return;
|
|
433
|
+
const { offsetWidth, scrollLeft } = tableContainer.value || {};
|
|
434
|
+
virtualScrollX.value.containerWidth = offsetWidth || Default_Table_Width;
|
|
435
|
+
updateVirtualScrollX(scrollLeft);
|
|
436
|
+
}
|
|
437
|
+
function initVirtualScroll(height) {
|
|
438
|
+
initVirtualScrollY(height);
|
|
439
|
+
initVirtualScrollX();
|
|
342
440
|
}
|
|
343
441
|
function updateVirtualScrollY(sTop = 0) {
|
|
344
442
|
const { rowHeight } = virtualScroll.value;
|
|
@@ -390,6 +488,7 @@ function useVirtualScroll({ tableContainer, props, dataSourceCopy, tableHeaderLa
|
|
|
390
488
|
virtualX_on,
|
|
391
489
|
virtualX_columnPart,
|
|
392
490
|
virtualX_offsetRight,
|
|
491
|
+
initVirtualScroll,
|
|
393
492
|
initVirtualScrollY,
|
|
394
493
|
initVirtualScrollX,
|
|
395
494
|
updateVirtualScrollY,
|
|
@@ -444,6 +543,8 @@ function strCompare(a, b, type) {
|
|
|
444
543
|
}
|
|
445
544
|
}
|
|
446
545
|
function tableSort(sortOption, order, dataSource) {
|
|
546
|
+
if (!(dataSource == null ? void 0 : dataSource.length))
|
|
547
|
+
return dataSource || [];
|
|
447
548
|
let targetDataSource = [...dataSource];
|
|
448
549
|
if (typeof sortOption.sorter === "function") {
|
|
449
550
|
const customSorterData = sortOption.sorter(targetDataSource, { order, column: sortOption });
|
|
@@ -563,7 +664,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
563
664
|
rowClassName: { type: Function, default: () => "" },
|
|
564
665
|
colResizable: { type: Boolean, default: false },
|
|
565
666
|
colMinWidth: { default: 10 },
|
|
566
|
-
bordered: { type: [Boolean, String], default: true }
|
|
667
|
+
bordered: { type: [Boolean, String], default: true },
|
|
668
|
+
autoResize: { type: Boolean, default: true }
|
|
567
669
|
},
|
|
568
670
|
emits: [
|
|
569
671
|
"sort-change",
|
|
@@ -607,15 +709,19 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
607
709
|
const store = {};
|
|
608
710
|
const cols = [...tableHeaderLast.value];
|
|
609
711
|
let left = 0;
|
|
712
|
+
let rightStartIndex = 0;
|
|
610
713
|
for (let i = 0; i < cols.length; i++) {
|
|
611
714
|
const item = cols[i];
|
|
612
715
|
if (item.fixed === "left") {
|
|
613
716
|
store[item.dataIndex] = left;
|
|
614
717
|
left += parseInt(item.width || Default_Col_Width);
|
|
615
718
|
}
|
|
719
|
+
if (!rightStartIndex && item.fixed === "right") {
|
|
720
|
+
rightStartIndex = i;
|
|
721
|
+
}
|
|
616
722
|
}
|
|
617
723
|
let right = 0;
|
|
618
|
-
for (let i = cols.length - 1; i >=
|
|
724
|
+
for (let i = cols.length - 1; i >= rightStartIndex; i--) {
|
|
619
725
|
const item = cols[i];
|
|
620
726
|
if (item.fixed === "right") {
|
|
621
727
|
store[item.dataIndex] = right;
|
|
@@ -642,12 +748,21 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
642
748
|
virtualX_on,
|
|
643
749
|
virtualX_columnPart,
|
|
644
750
|
virtualX_offsetRight,
|
|
751
|
+
initVirtualScroll,
|
|
645
752
|
initVirtualScrollY,
|
|
646
753
|
initVirtualScrollX,
|
|
647
754
|
updateVirtualScrollY,
|
|
648
755
|
updateVirtualScrollX
|
|
649
756
|
} = useVirtualScroll({ tableContainer, props, dataSourceCopy, tableHeaderLast });
|
|
650
757
|
const { setHighlightDimCell, setHighlightDimRow } = useHighlight({ props, tableContainer, rowKeyGen });
|
|
758
|
+
if (props.autoResize) {
|
|
759
|
+
useAutoResize({ tableContainer, initVirtualScroll, scrollTo, props, debounceMs: 500 });
|
|
760
|
+
}
|
|
761
|
+
useKeyboardArrowScroll(tableContainer, {
|
|
762
|
+
scrollTo,
|
|
763
|
+
virtualScroll,
|
|
764
|
+
virtualScrollX
|
|
765
|
+
});
|
|
651
766
|
watch(
|
|
652
767
|
() => props.columns,
|
|
653
768
|
() => {
|
|
@@ -659,6 +774,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
659
774
|
watch(
|
|
660
775
|
() => props.dataSource,
|
|
661
776
|
(val) => {
|
|
777
|
+
if (!val) {
|
|
778
|
+
console.warn("invalid dataSource");
|
|
779
|
+
return;
|
|
780
|
+
}
|
|
662
781
|
let needInitVirtualScrollY = false;
|
|
663
782
|
if (dataSourceCopy.value.length !== val.length) {
|
|
664
783
|
needInitVirtualScrollY = true;
|
|
@@ -678,10 +797,6 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
678
797
|
onMounted(() => {
|
|
679
798
|
initVirtualScroll();
|
|
680
799
|
});
|
|
681
|
-
function initVirtualScroll(height) {
|
|
682
|
-
initVirtualScrollY(height);
|
|
683
|
-
initVirtualScrollX();
|
|
684
|
-
}
|
|
685
800
|
function getFixedStyle(tagType, col) {
|
|
686
801
|
const style = {};
|
|
687
802
|
if (Is_Legacy_Mode) {
|
|
@@ -909,6 +1024,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
909
1024
|
setCurrentRow,
|
|
910
1025
|
setHighlightDimCell,
|
|
911
1026
|
setHighlightDimRow,
|
|
1027
|
+
sortCol,
|
|
912
1028
|
setSorter,
|
|
913
1029
|
resetSorter,
|
|
914
1030
|
scrollTo,
|
|
@@ -974,7 +1090,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
974
1090
|
col.dataIndex === unref(sortCol) && unref(sortOrderIndex) !== 0 && "sorter-" + sortSwitchOrder[unref(sortOrderIndex)],
|
|
975
1091
|
_ctx.showHeaderOverflow ? "text-overflow" : "",
|
|
976
1092
|
col.headerClassName,
|
|
977
|
-
col.fixed ? "fixed-cell" : ""
|
|
1093
|
+
col.fixed ? "fixed-cell" : "",
|
|
1094
|
+
col.fixed ? "fixed-cell--" + col.fixed : ""
|
|
978
1095
|
]),
|
|
979
1096
|
onClick: (e) => {
|
|
980
1097
|
onColumnSort(col);
|
|
@@ -1057,7 +1174,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1057
1174
|
return openBlock(), createElementBlock("td", {
|
|
1058
1175
|
key: col.dataIndex,
|
|
1059
1176
|
"data-index": col.dataIndex,
|
|
1060
|
-
class: normalizeClass([
|
|
1177
|
+
class: normalizeClass([
|
|
1178
|
+
col.className,
|
|
1179
|
+
_ctx.showOverflow ? "text-overflow" : "",
|
|
1180
|
+
col.fixed ? "fixed-cell" : "",
|
|
1181
|
+
col.fixed ? "fixed-cell--" + col.fixed : ""
|
|
1182
|
+
]),
|
|
1061
1183
|
style: normalizeStyle(getCellStyle(2, col)),
|
|
1062
1184
|
onClick: (e) => onCellClick(e, row, col)
|
|
1063
1185
|
}, [
|