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.
@@ -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
- const ARROW_CODES = ['ArrowUp', 'ArrowRight', 'ArrowDown', 'ArrowLeft'];
5
+ /** 翻页按键 */
6
+ const SCROLL_CODES = ['ArrowUp', 'ArrowRight', 'ArrowDown', 'ArrowLeft', 'PageUp', 'PageDown'] as const;
5
7
 
6
- type Options = {
7
- scrollTo: (x: number | null, y: number | null) => void;
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(targetElement: Ref<HTMLElement | undefined>, { scrollTo, virtualScroll, virtualScrollX }: Options) {
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 (!ARROW_CODES.includes(e.code)) return;
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
- if (e.code === ARROW_CODES[0]) {
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 === ARROW_CODES[1]) {
54
+ } else if (e.code === SCROLL_CODES[1]) {
45
55
  scrollTo(null, scrollLeft + rowHeight);
46
- } else if (e.code === ARROW_CODES[2]) {
56
+ } else if (e.code === SCROLL_CODES[2]) {
47
57
  scrollTo(scrollTop + rowHeight, null);
48
- } else if (e.code === ARROW_CODES[3]) {
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>>({ tableContainer, props, dataSourceCopy, tableHeaderLast }: Option<DT>) {
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 * 1.5
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
- Object.assign(virtualScroll.value, {
178
- startIndex,
179
- offsetTop: startIndex * rowHeight, // startIndex之前的高度
180
- endIndex,
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
- Object.assign(virtualScrollX.value, { startIndex, endIndex, offsetLeft });
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
@@ -1,3 +1,4 @@
1
+ /// <reference types="vite/client" />
1
2
  declare module '*.vue' {
2
3
  import { DefineComponent } from 'vue';
3
4
  const component: DefineComponent<object, object, any>;