stk-table-vue 0.0.2 → 0.2.0
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 +137 -5
- package/lib/src/StkTable/StkTable.vue.d.ts +367 -335
- package/lib/src/StkTable/const.d.ts +1 -0
- package/lib/src/StkTable/types/index.d.ts +73 -60
- package/lib/src/StkTable/useColResize.d.ts +18 -18
- package/lib/src/StkTable/useFixedCol.d.ts +20 -0
- package/lib/src/StkTable/useFixedStyle.d.ts +20 -20
- package/lib/src/StkTable/useKeyboardArrowScroll.d.ts +17 -14
- package/lib/src/StkTable/useThDrag.d.ts +14 -14
- package/lib/src/StkTable/useVirtualScroll.d.ts +73 -73
- package/lib/src/StkTable/utils.d.ts +23 -23
- package/lib/stk-table-vue.js +1490 -1269
- package/lib/style.css +294 -286
- package/package.json +1 -1
- package/src/StkTable/StkTable.vue +149 -64
- package/src/StkTable/const.ts +1 -0
- package/src/StkTable/style.less +191 -237
- package/src/StkTable/types/index.ts +15 -2
- package/src/StkTable/useFixedCol.ts +91 -0
- package/src/StkTable/useKeyboardArrowScroll.ts +24 -10
- package/src/StkTable/useVirtualScroll.ts +50 -10
- package/src/vite-env.d.ts +1 -0
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
import { Ref, onBeforeUnmount, onMounted } from 'vue';
|
|
2
|
+
import { StkTableColumn } from './types';
|
|
2
3
|
import { VirtualScrollStore, VirtualScrollXStore } from './useVirtualScroll';
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
/** 翻页按键 */
|
|
6
|
+
const SCROLL_CODES = ['ArrowUp', 'ArrowRight', 'ArrowDown', 'ArrowLeft', 'PageUp', 'PageDown'] as const;
|
|
5
7
|
|
|
6
|
-
type Options = {
|
|
7
|
-
|
|
8
|
+
type Options<DT extends Record<string, any>> = {
|
|
9
|
+
props: any;
|
|
10
|
+
scrollTo: (y: number | null, x: number | null) => void;
|
|
8
11
|
virtualScroll: Ref<VirtualScrollStore>;
|
|
9
12
|
virtualScrollX: Ref<VirtualScrollXStore>;
|
|
13
|
+
tableHeaders: Ref<StkTableColumn<DT>[][]>;
|
|
10
14
|
};
|
|
11
15
|
/**
|
|
12
16
|
* 按下键盘箭头滚动。只有悬浮在表体上才能生效键盘。
|
|
13
17
|
*
|
|
14
18
|
* 在低版本浏览器中,虚拟滚动时,使用键盘滚动,等选中的行消失在视口外时,滚动会失效。
|
|
15
19
|
*/
|
|
16
|
-
export function useKeyboardArrowScroll
|
|
20
|
+
export function useKeyboardArrowScroll<DT extends Record<string, any>>(
|
|
21
|
+
targetElement: Ref<HTMLElement | undefined>,
|
|
22
|
+
{ props, scrollTo, virtualScroll, virtualScrollX, tableHeaders }: Options<DT>,
|
|
23
|
+
) {
|
|
17
24
|
/** 检测鼠标是否悬浮在表格体上 */
|
|
18
25
|
let isMouseOver = false;
|
|
19
26
|
|
|
@@ -33,20 +40,27 @@ export function useKeyboardArrowScroll(targetElement: Ref<HTMLElement | undefine
|
|
|
33
40
|
|
|
34
41
|
/** 键盘按下事件 */
|
|
35
42
|
function handleKeydown(e: KeyboardEvent) {
|
|
36
|
-
if (!
|
|
43
|
+
if (!SCROLL_CODES.includes(e.code as any)) return;
|
|
37
44
|
if (!isMouseOver) return; // 不悬浮还是要触发键盘事件的
|
|
38
45
|
e.preventDefault(); // 不触发键盘默认的箭头事件
|
|
39
46
|
|
|
40
|
-
const { scrollTop, rowHeight } = virtualScroll.value;
|
|
47
|
+
const { scrollTop, rowHeight, pageSize } = virtualScroll.value;
|
|
41
48
|
const { scrollLeft } = virtualScrollX.value;
|
|
42
|
-
|
|
49
|
+
const { headless, headerRowHeight } = props;
|
|
50
|
+
/**表头高度 */
|
|
51
|
+
const headerHeight = headless ? 0 : tableHeaders.value.length * (headerRowHeight || rowHeight);
|
|
52
|
+
if (e.code === SCROLL_CODES[0]) {
|
|
43
53
|
scrollTo(scrollTop - rowHeight, null);
|
|
44
|
-
} else if (e.code ===
|
|
54
|
+
} else if (e.code === SCROLL_CODES[1]) {
|
|
45
55
|
scrollTo(null, scrollLeft + rowHeight);
|
|
46
|
-
} else if (e.code ===
|
|
56
|
+
} else if (e.code === SCROLL_CODES[2]) {
|
|
47
57
|
scrollTo(scrollTop + rowHeight, null);
|
|
48
|
-
} else if (e.code ===
|
|
58
|
+
} else if (e.code === SCROLL_CODES[3]) {
|
|
49
59
|
scrollTo(null, scrollLeft - rowHeight);
|
|
60
|
+
} else if (e.code === SCROLL_CODES[4]) {
|
|
61
|
+
scrollTo(scrollTop - rowHeight * pageSize - headerHeight, null);
|
|
62
|
+
} else if (e.code === SCROLL_CODES[5]) {
|
|
63
|
+
scrollTo(scrollTop + rowHeight * pageSize - headerHeight, null);
|
|
50
64
|
}
|
|
51
65
|
}
|
|
52
66
|
|
|
@@ -45,12 +45,15 @@ function getCalcWidth<DT extends Record<string, any>>(col: StkTableColumn<DT>) {
|
|
|
45
45
|
return parseInt(col.minWidth || col.width || Default_Col_Width);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
/** vue2 优化滚动回收延时 */
|
|
49
|
+
const VUE2_SCROLL_TIMEOUT_MS = 200;
|
|
50
|
+
|
|
48
51
|
/**
|
|
49
52
|
* 虚拟滚动
|
|
50
53
|
* @param param0
|
|
51
54
|
* @returns
|
|
52
55
|
*/
|
|
53
|
-
export function useVirtualScroll<DT extends Record<string, any>>({
|
|
56
|
+
export function useVirtualScroll<DT extends Record<string, any>>({ props, tableContainer, dataSourceCopy, tableHeaderLast }: Option<DT>) {
|
|
54
57
|
const virtualScroll = ref<VirtualScrollStore>({
|
|
55
58
|
containerHeight: 0,
|
|
56
59
|
rowHeight: props.rowHeight,
|
|
@@ -88,7 +91,7 @@ export function useVirtualScroll<DT extends Record<string, any>>({ tableContaine
|
|
|
88
91
|
|
|
89
92
|
const virtualX_on = computed(() => {
|
|
90
93
|
return (
|
|
91
|
-
props.virtualX && tableHeaderLast.value.reduce((sum, col) => (sum += getCalcWidth(col)), 0) > virtualScrollX.value.containerWidth
|
|
94
|
+
props.virtualX && tableHeaderLast.value.reduce((sum, col) => (sum += getCalcWidth(col)), 0) > virtualScrollX.value.containerWidth + 100
|
|
92
95
|
);
|
|
93
96
|
});
|
|
94
97
|
|
|
@@ -166,24 +169,46 @@ export function useVirtualScroll<DT extends Record<string, any>>({ tableContaine
|
|
|
166
169
|
initVirtualScrollX();
|
|
167
170
|
}
|
|
168
171
|
|
|
172
|
+
let vue2ScrollYTimeout: null | number = null;
|
|
173
|
+
|
|
169
174
|
/** 通过滚动条位置,计算虚拟滚动的参数 */
|
|
170
175
|
function updateVirtualScrollY(sTop = 0) {
|
|
171
|
-
const { rowHeight, pageSize } = virtualScroll.value;
|
|
176
|
+
const { rowHeight, pageSize, scrollTop, startIndex: oldStartIndex } = virtualScroll.value;
|
|
172
177
|
const startIndex = Math.floor(sTop / rowHeight);
|
|
178
|
+
const offsetTop = startIndex * rowHeight; // startIndex之前的高度
|
|
173
179
|
let endIndex = startIndex + pageSize;
|
|
174
180
|
if (endIndex > dataSourceCopy.value.length) {
|
|
175
181
|
endIndex = dataSourceCopy.value.length; // 溢出index修正
|
|
176
182
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
183
|
+
if (vue2ScrollYTimeout) {
|
|
184
|
+
window.clearTimeout(vue2ScrollYTimeout);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* 一次滚动大于一页时表示滚动过快,回退优化
|
|
188
|
+
*/
|
|
189
|
+
if (!props.optimizeVue2Scroll || sTop <= scrollTop || Math.abs(oldStartIndex - startIndex) >= pageSize) {
|
|
190
|
+
// 向上滚动
|
|
191
|
+
Object.assign(virtualScroll.value, {
|
|
192
|
+
startIndex,
|
|
193
|
+
offsetTop,
|
|
194
|
+
endIndex,
|
|
195
|
+
scrollTop: sTop,
|
|
196
|
+
});
|
|
197
|
+
} else {
|
|
198
|
+
// vue2向下滚动优化
|
|
199
|
+
Object.assign(virtualScroll.value, { endIndex, scrollTop: sTop });
|
|
200
|
+
vue2ScrollYTimeout = window.setTimeout(() => {
|
|
201
|
+
Object.assign(virtualScroll.value, { startIndex, offsetTop });
|
|
202
|
+
}, VUE2_SCROLL_TIMEOUT_MS);
|
|
203
|
+
}
|
|
182
204
|
}
|
|
183
205
|
|
|
206
|
+
let vue2ScrollXTimeout: null | number = null;
|
|
207
|
+
|
|
184
208
|
/** 通过横向滚动条位置,计算横向虚拟滚动的参数 */
|
|
185
209
|
function updateVirtualScrollX(sLeft = 0) {
|
|
186
210
|
const headerLength = tableHeaderLast.value?.length;
|
|
211
|
+
const { scrollLeft } = virtualScrollX.value;
|
|
187
212
|
if (!headerLength) return;
|
|
188
213
|
let startIndex = 0;
|
|
189
214
|
let offsetLeft = 0;
|
|
@@ -206,7 +231,7 @@ export function useVirtualScroll<DT extends Record<string, any>>({ tableContaine
|
|
|
206
231
|
// -----
|
|
207
232
|
colWidthSum = 0;
|
|
208
233
|
let endIndex = headerLength;
|
|
209
|
-
for (let colIndex = startIndex; colIndex < headerLength; colIndex++) {
|
|
234
|
+
for (let colIndex = startIndex + 1; colIndex < headerLength; colIndex++) {
|
|
210
235
|
const col = tableHeaderLast.value[colIndex];
|
|
211
236
|
colWidthSum += getCalcWidth(col);
|
|
212
237
|
// 列宽大于容器宽度则停止
|
|
@@ -218,7 +243,22 @@ export function useVirtualScroll<DT extends Record<string, any>>({ tableContaine
|
|
|
218
243
|
if (endIndex > headerLength) {
|
|
219
244
|
endIndex = headerLength;
|
|
220
245
|
}
|
|
221
|
-
|
|
246
|
+
|
|
247
|
+
if (vue2ScrollXTimeout) {
|
|
248
|
+
window.clearTimeout(vue2ScrollXTimeout);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// <= 等于是因为初始化时要赋值
|
|
252
|
+
if (!props.optimizeVue2Scroll || sLeft <= scrollLeft) {
|
|
253
|
+
// 向左滚动
|
|
254
|
+
Object.assign(virtualScrollX.value, { startIndex, endIndex, offsetLeft, scrollLeft: sLeft });
|
|
255
|
+
} else {
|
|
256
|
+
//vue2 向右滚动 优化
|
|
257
|
+
Object.assign(virtualScrollX.value, { endIndex, scrollLeft: sLeft });
|
|
258
|
+
vue2ScrollXTimeout = window.setTimeout(() => {
|
|
259
|
+
Object.assign(virtualScrollX.value, { startIndex, offsetLeft });
|
|
260
|
+
}, VUE2_SCROLL_TIMEOUT_MS);
|
|
261
|
+
}
|
|
222
262
|
}
|
|
223
263
|
|
|
224
264
|
return {
|
package/src/vite-env.d.ts
CHANGED