stk-table-vue 0.11.3 → 0.11.4
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/lib/index-t5SJ6KNv.js +1 -1
- package/lib/src/StkTable/StkTable.vue.d.ts +15 -33
- package/lib/src/StkTable/useSorter.d.ts +38 -0
- package/lib/stk-table-vue.js +179 -160
- package/lib/style.css +1 -1
- package/package.json +1 -1
- package/src/StkTable/StkTable.vue +21 -242
- package/src/StkTable/useSorter.ts +262 -0
- package/src/StkTable/useVirtualScroll.ts +6 -2
package/lib/index-t5SJ6KNv.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FilterStatus } from './components/Filter/types';
|
|
2
|
-
import { AreaSelectionConfig, AreaSelectionRange, AutoRowHeightConfig, ColResizableConfig, DragRowConfig, ExpandConfig, ExperimentalConfig, FooterConfig, HeaderDragConfig, HighlightConfig, Order, PrivateRowDT, PrivateStkTableColumn, RowActiveOption, SeqConfig, SortConfig,
|
|
2
|
+
import { AreaSelectionConfig, AreaSelectionRange, AutoRowHeightConfig, ColResizableConfig, DragRowConfig, ExpandConfig, ExperimentalConfig, FooterConfig, HeaderDragConfig, HighlightConfig, Order, PrivateRowDT, PrivateStkTableColumn, RowActiveOption, SeqConfig, SortConfig, StkTableColumn, TreeConfig, UniqKey, UniqKeyProp } from './types/index';
|
|
3
3
|
import { ScrollbarOptions } from './useScrollbar';
|
|
4
4
|
|
|
5
5
|
/** Generic stands for DataType */
|
|
@@ -28,25 +28,6 @@ declare function setCurrentRow(rowKeyOrRow: string | undefined | DT, option?: {
|
|
|
28
28
|
declare function setSelectedCell(row?: DT, col?: StkTableColumn<DT>, option?: {
|
|
29
29
|
silent: boolean;
|
|
30
30
|
}): void;
|
|
31
|
-
/**
|
|
32
|
-
* 设置表头排序状态。
|
|
33
|
-
* @param colKey 列唯一键字段。如果你想要取消排序状态,请使用`resetSorter`
|
|
34
|
-
* @param order 正序倒序
|
|
35
|
-
* @param option.sortOption 指定排序参数。同 StkTableColumn 中排序相关字段。建议从columns中find得到。
|
|
36
|
-
* @param option.sort 是否触发排序-默认true
|
|
37
|
-
* @param option.silent 是否禁止触发回调-默认true
|
|
38
|
-
* @param option.force 是否触发排序-默认true
|
|
39
|
-
* @param option.append 是否追加排序(多列排序模式)。为true时保留现有排序状态,将新排序添加到最前面;为false时替换所有排序状态
|
|
40
|
-
* @return 表格数据
|
|
41
|
-
*/
|
|
42
|
-
declare function setSorter(colKey: string, order: Order, option?: {
|
|
43
|
-
sortOption?: SortOption<DT>;
|
|
44
|
-
force?: boolean;
|
|
45
|
-
silent?: boolean;
|
|
46
|
-
sort?: boolean;
|
|
47
|
-
append?: boolean;
|
|
48
|
-
}): any[];
|
|
49
|
-
declare function resetSorter(): void;
|
|
50
31
|
/**
|
|
51
32
|
* set scroll bar position
|
|
52
33
|
* @param top null to not change
|
|
@@ -55,14 +36,6 @@ declare function resetSorter(): void;
|
|
|
55
36
|
declare function scrollTo(top?: number | null, left?: number | null): void;
|
|
56
37
|
/** get current table data */
|
|
57
38
|
declare function getTableData(): any[];
|
|
58
|
-
/**
|
|
59
|
-
* get current sort info
|
|
60
|
-
* @return {{key:string,order:Order}[]}
|
|
61
|
-
*/
|
|
62
|
-
declare function getSortColumns(): {
|
|
63
|
-
key: keyof DT | undefined;
|
|
64
|
-
order: Order;
|
|
65
|
-
}[];
|
|
66
39
|
declare function __VLS_template(): {
|
|
67
40
|
tableHeader?(_: {
|
|
68
41
|
col: PrivateStkTableColumn<PrivateRowDT>;
|
|
@@ -359,34 +332,43 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
|
|
|
359
332
|
sortField?: string | number | symbol | undefined;
|
|
360
333
|
sortType?: "number" | "string" | undefined;
|
|
361
334
|
order: Order;
|
|
362
|
-
}[],
|
|
335
|
+
}[], {
|
|
363
336
|
key?: any;
|
|
364
337
|
dataIndex: string;
|
|
365
338
|
sortField?: string | number | symbol | undefined;
|
|
366
339
|
sortType?: "number" | "string" | undefined;
|
|
367
340
|
order: Order;
|
|
368
|
-
}[]>;
|
|
341
|
+
}[] | import('.').SortState<any>[]>;
|
|
369
342
|
/**
|
|
370
343
|
* 表格排序列顺序
|
|
371
344
|
*
|
|
372
345
|
* en: get current sort info
|
|
373
346
|
* @see {@link getSortColumns}
|
|
374
347
|
*/
|
|
375
|
-
getSortColumns:
|
|
348
|
+
getSortColumns: () => {
|
|
349
|
+
key: string | number | symbol | undefined;
|
|
350
|
+
order: Order;
|
|
351
|
+
}[];
|
|
376
352
|
/**
|
|
377
353
|
* 设置表头排序状态
|
|
378
354
|
*
|
|
379
355
|
* en: Set the sort status of the table header
|
|
380
356
|
* @see {@link setSorter}
|
|
381
357
|
*/
|
|
382
|
-
setSorter:
|
|
358
|
+
setSorter: (colKey: string, order: Order, option?: {
|
|
359
|
+
sortOption?: import('.').SortOption<any> | undefined;
|
|
360
|
+
force?: boolean;
|
|
361
|
+
silent?: boolean;
|
|
362
|
+
sort?: boolean;
|
|
363
|
+
append?: boolean;
|
|
364
|
+
}) => any[];
|
|
383
365
|
/**
|
|
384
366
|
* 重置sorter状态
|
|
385
367
|
*
|
|
386
368
|
* en: Reset the sorter status
|
|
387
369
|
* @see {@link resetSorter}
|
|
388
370
|
*/
|
|
389
|
-
resetSorter:
|
|
371
|
+
resetSorter: () => void;
|
|
390
372
|
/**
|
|
391
373
|
* 滚动至
|
|
392
374
|
*
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Ref } from 'vue';
|
|
2
|
+
import { Order, SortOption, SortState, StkTableColumn, UniqKey } from './types/index';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 排序 Hook
|
|
6
|
+
* 管理表格排序状态和相关操作
|
|
7
|
+
* @param props 表格 props
|
|
8
|
+
* @param colKeyGen 列 key 生成函数
|
|
9
|
+
* @param tableHeaderLast 表头最后一行(叶子节点)
|
|
10
|
+
* @param dataSourceCopy 数据源副本 ref
|
|
11
|
+
* @param initDataSource 初始化数据源函数
|
|
12
|
+
* @param emits 事件发射函数
|
|
13
|
+
* @returns 排序相关状态和方法
|
|
14
|
+
*/
|
|
15
|
+
export declare function useSorter<DT extends Record<string, any>>(props: any, emits: any, colKeyGen: Ref<(col: StkTableColumn<DT>) => string>, tableHeaderLast: Ref<StkTableColumn<DT>[]>, dataSourceCopy: Ref<DT[]>, initDataSource: (data?: DT[], option?: {
|
|
16
|
+
forceSort?: boolean;
|
|
17
|
+
}) => void): readonly [Ref<{
|
|
18
|
+
key?: any;
|
|
19
|
+
dataIndex: import('vue').UnwrapRef<keyof DT & string>;
|
|
20
|
+
sortField?: import('vue').UnwrapRef<keyof DT> | undefined;
|
|
21
|
+
sortType?: "number" | "string" | undefined;
|
|
22
|
+
order: Order;
|
|
23
|
+
}[], SortState<DT>[] | {
|
|
24
|
+
key?: any;
|
|
25
|
+
dataIndex: import('vue').UnwrapRef<keyof DT & string>;
|
|
26
|
+
sortField?: import('vue').UnwrapRef<keyof DT> | undefined;
|
|
27
|
+
sortType?: "number" | "string" | undefined;
|
|
28
|
+
order: Order;
|
|
29
|
+
}[]>, import('vue').ComputedRef<keyof DT | undefined>, (col: StkTableColumn<DT> | undefined | null) => void, (colKey: string, order: Order, option?: {
|
|
30
|
+
sortOption?: SortOption<DT>;
|
|
31
|
+
force?: boolean;
|
|
32
|
+
silent?: boolean;
|
|
33
|
+
sort?: boolean;
|
|
34
|
+
append?: boolean;
|
|
35
|
+
}) => DT[], () => void, () => {
|
|
36
|
+
key: keyof DT | undefined;
|
|
37
|
+
order: Order;
|
|
38
|
+
}[], () => void, (colKey: UniqKey) => SortState<DT> | undefined, (dataSource: DT[]) => DT[]];
|
package/lib/stk-table-vue.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* name: stk-table-vue
|
|
3
|
-
* version: v0.11.
|
|
3
|
+
* version: v0.11.4
|
|
4
4
|
* description: High performance realtime virtual table for vue3 and vue2.7
|
|
5
5
|
* author: japlus
|
|
6
6
|
* homepage: https://ja-plus.github.io/stk-table-vue/
|
|
7
7
|
* license: MIT
|
|
8
8
|
*/
|
|
9
|
-
import { createElementBlock, openBlock, createElementVNode, defineComponent, normalizeStyle, createBlock, createCommentVNode, toDisplayString, ref, computed, onMounted, onBeforeUnmount, watch, shallowRef, onUnmounted, nextTick, customRef, provide, toRef,
|
|
9
|
+
import { createElementBlock, openBlock, createElementVNode, defineComponent, normalizeStyle, createBlock, createCommentVNode, toDisplayString, ref, computed, onMounted, onBeforeUnmount, watch, shallowRef, onUnmounted, nextTick, customRef, toRaw, provide, toRef, normalizeClass, unref, renderSlot, Fragment, renderList, mergeProps, resolveDynamicComponent, withCtx, createTextVNode, createVNode, createApp, markRaw, getCurrentInstance, h } from "vue";
|
|
10
10
|
const _export_sfc = (sfc, props) => {
|
|
11
11
|
const target = sfc.__vccOpts || sfc;
|
|
12
12
|
for (const [key, val] of props) {
|
|
@@ -2258,7 +2258,7 @@ function useVirtualScroll(props, tableContainerRef, trRef, dataSourceCopy, table
|
|
|
2258
2258
|
const headerToBodyRowHeightCount = Math.floor(tableHeaderHeight.value / rowHeight);
|
|
2259
2259
|
pageSize -= headerToBodyRowHeightCount;
|
|
2260
2260
|
}
|
|
2261
|
-
const maxScrollTop = dataSourceCopy.value.length * rowHeight + tableHeaderHeight.value - containerHeight;
|
|
2261
|
+
const maxScrollTop = Math.max(0, dataSourceCopy.value.length * rowHeight + tableHeaderHeight.value - containerHeight);
|
|
2262
2262
|
if (scrollTop > maxScrollTop) {
|
|
2263
2263
|
scrollTop = maxScrollTop;
|
|
2264
2264
|
}
|
|
@@ -2306,7 +2306,14 @@ function useVirtualScroll(props, tableContainerRef, trRef, dataSourceCopy, table
|
|
|
2306
2306
|
const dataSourceCopyTemp = dataSourceCopy.value;
|
|
2307
2307
|
const dataLength = dataSourceCopyTemp.length;
|
|
2308
2308
|
const rowHeight = getRowHeightFn.value();
|
|
2309
|
-
const vsValue = {
|
|
2309
|
+
const vsValue = {
|
|
2310
|
+
startIndex: 0,
|
|
2311
|
+
// github #34 init
|
|
2312
|
+
endIndex: dataLength,
|
|
2313
|
+
// github #34 init
|
|
2314
|
+
offsetTop: 0
|
|
2315
|
+
// github #34 init
|
|
2316
|
+
};
|
|
2310
2317
|
const scrollHeight = dataLength * rowHeight + tableHeaderHeight.value;
|
|
2311
2318
|
const { enabled: scrollbarEnable } = scrollbarOptions.value;
|
|
2312
2319
|
if (scrollbarEnable) {
|
|
@@ -2505,6 +2512,162 @@ function useWheeling(resetDelay = 500) {
|
|
|
2505
2512
|
};
|
|
2506
2513
|
return [get, set];
|
|
2507
2514
|
}
|
|
2515
|
+
const SORT_SWITCH_ORDER = [null, "desc", "asc"];
|
|
2516
|
+
function useSorter(props, emits, colKeyGen, tableHeaderLast, dataSourceCopy, initDataSource) {
|
|
2517
|
+
const sortStates = ref([]);
|
|
2518
|
+
const isMultiSort = computed(() => props.sortConfig.multiSort ?? false);
|
|
2519
|
+
const multiSortLimit = computed(() => props.sortConfig.multiSortLimit ?? 3);
|
|
2520
|
+
const sortCol = computed(() => {
|
|
2521
|
+
var _a;
|
|
2522
|
+
return (_a = sortStates.value[0]) == null ? void 0 : _a.dataIndex;
|
|
2523
|
+
});
|
|
2524
|
+
function getColumnSortState(colKey) {
|
|
2525
|
+
return sortStates.value[getSortStateIndex(colKey)];
|
|
2526
|
+
}
|
|
2527
|
+
function getSortStateIndex(colKey) {
|
|
2528
|
+
return sortStates.value.findIndex((s) => s.key === colKey || s.dataIndex === colKey);
|
|
2529
|
+
}
|
|
2530
|
+
function addOrUpdateSortState(newState, mode) {
|
|
2531
|
+
const existingIndex = sortStates.value.findIndex((s) => s.key === newState.key || s.dataIndex === newState.dataIndex);
|
|
2532
|
+
if (existingIndex >= 0) {
|
|
2533
|
+
sortStates.value.splice(existingIndex, 1);
|
|
2534
|
+
}
|
|
2535
|
+
if (mode && isMultiSort.value) {
|
|
2536
|
+
if (sortStates.value.length >= multiSortLimit.value) {
|
|
2537
|
+
sortStates.value.pop();
|
|
2538
|
+
}
|
|
2539
|
+
sortStates.value.unshift(newState);
|
|
2540
|
+
} else {
|
|
2541
|
+
sortStates.value = [newState];
|
|
2542
|
+
}
|
|
2543
|
+
}
|
|
2544
|
+
function updateSortState(col, colKey) {
|
|
2545
|
+
const existingIndex = getSortStateIndex(colKey);
|
|
2546
|
+
let newOrder;
|
|
2547
|
+
if (existingIndex >= 0) {
|
|
2548
|
+
const currentOrder = sortStates.value[existingIndex].order;
|
|
2549
|
+
const currentIndex = SORT_SWITCH_ORDER.indexOf(currentOrder);
|
|
2550
|
+
newOrder = SORT_SWITCH_ORDER[(currentIndex + 1) % 3];
|
|
2551
|
+
if (newOrder === null) {
|
|
2552
|
+
sortStates.value.splice(existingIndex, 1);
|
|
2553
|
+
} else {
|
|
2554
|
+
const updatedState = { ...sortStates.value[existingIndex], order: newOrder };
|
|
2555
|
+
addOrUpdateSortState(updatedState, 1);
|
|
2556
|
+
}
|
|
2557
|
+
} else {
|
|
2558
|
+
newOrder = SORT_SWITCH_ORDER[1];
|
|
2559
|
+
const newState = {
|
|
2560
|
+
key: colKey,
|
|
2561
|
+
dataIndex: col.dataIndex,
|
|
2562
|
+
sortField: col.sortField,
|
|
2563
|
+
sortType: col.sortType,
|
|
2564
|
+
order: newOrder
|
|
2565
|
+
};
|
|
2566
|
+
addOrUpdateSortState(newState, 1);
|
|
2567
|
+
}
|
|
2568
|
+
return newOrder;
|
|
2569
|
+
}
|
|
2570
|
+
function sortData(dataSource) {
|
|
2571
|
+
if (!sortStates.value.length) return dataSource;
|
|
2572
|
+
const sortConfig = { ...DEFAULT_SORT_CONFIG, ...props.sortConfig };
|
|
2573
|
+
let result = dataSource.slice();
|
|
2574
|
+
for (let i = sortStates.value.length - 1; i >= 0; i--) {
|
|
2575
|
+
const state = sortStates.value[i];
|
|
2576
|
+
const col = tableHeaderLast.value.find((c) => state.key && colKeyGen.value(c) === state.key || c.dataIndex === state.dataIndex);
|
|
2577
|
+
if (col && state.order) {
|
|
2578
|
+
const colSortConfig = { ...sortConfig, ...col.sortConfig };
|
|
2579
|
+
result = tableSort(col, state.order, result, colSortConfig);
|
|
2580
|
+
}
|
|
2581
|
+
}
|
|
2582
|
+
return result;
|
|
2583
|
+
}
|
|
2584
|
+
function onColumnSort(col) {
|
|
2585
|
+
if (!col) {
|
|
2586
|
+
console.warn("onColumnSort: not found col:", col);
|
|
2587
|
+
return;
|
|
2588
|
+
}
|
|
2589
|
+
if (!col.sorter) {
|
|
2590
|
+
return;
|
|
2591
|
+
}
|
|
2592
|
+
const colKey = colKeyGen.value(col);
|
|
2593
|
+
let order = updateSortState(col, colKey);
|
|
2594
|
+
const sortConfig = { ...DEFAULT_SORT_CONFIG, ...props.sortConfig, ...col.sortConfig };
|
|
2595
|
+
if (!order && sortConfig.defaultSort) {
|
|
2596
|
+
const defaultColKey = sortConfig.defaultSort.key || sortConfig.defaultSort.dataIndex;
|
|
2597
|
+
if (defaultColKey) {
|
|
2598
|
+
const defaultCol = tableHeaderLast.value.find((item) => colKeyGen.value(item) === defaultColKey);
|
|
2599
|
+
if (defaultCol) {
|
|
2600
|
+
col = defaultCol;
|
|
2601
|
+
order = sortConfig.defaultSort.order;
|
|
2602
|
+
if (order) {
|
|
2603
|
+
addOrUpdateSortState({
|
|
2604
|
+
key: defaultColKey,
|
|
2605
|
+
dataIndex: defaultCol.dataIndex,
|
|
2606
|
+
sortField: defaultCol.sortField,
|
|
2607
|
+
sortType: defaultCol.sortType,
|
|
2608
|
+
order
|
|
2609
|
+
});
|
|
2610
|
+
}
|
|
2611
|
+
}
|
|
2612
|
+
}
|
|
2613
|
+
}
|
|
2614
|
+
if (!props.sortRemote) {
|
|
2615
|
+
initDataSource();
|
|
2616
|
+
}
|
|
2617
|
+
emits("sort-change", col, order, toRaw(dataSourceCopy.value), sortConfig);
|
|
2618
|
+
}
|
|
2619
|
+
function setSorter(colKey, order, option = {}) {
|
|
2620
|
+
var _a;
|
|
2621
|
+
const newOption = { silent: true, sortOption: null, sort: true, append: false, ...option };
|
|
2622
|
+
const colKeyGenValue = colKeyGen.value;
|
|
2623
|
+
let column;
|
|
2624
|
+
if (order) {
|
|
2625
|
+
column = newOption.sortOption || tableHeaderLast.value.find((it) => colKeyGenValue(it) === colKey);
|
|
2626
|
+
if (column) {
|
|
2627
|
+
const newState = {
|
|
2628
|
+
key: colKey,
|
|
2629
|
+
dataIndex: column.dataIndex,
|
|
2630
|
+
sortField: column.sortField,
|
|
2631
|
+
sortType: column.sortType,
|
|
2632
|
+
order
|
|
2633
|
+
};
|
|
2634
|
+
const mode = newOption.append && isMultiSort.value ? 1 : 0;
|
|
2635
|
+
addOrUpdateSortState(newState, mode);
|
|
2636
|
+
}
|
|
2637
|
+
} else {
|
|
2638
|
+
sortStates.value = [];
|
|
2639
|
+
}
|
|
2640
|
+
if (newOption.sort && ((_a = dataSourceCopy.value) == null ? void 0 : _a.length)) {
|
|
2641
|
+
if (!props.sortRemote || newOption.force) {
|
|
2642
|
+
initDataSource(props.dataSource, { forceSort: newOption.force });
|
|
2643
|
+
}
|
|
2644
|
+
}
|
|
2645
|
+
if (!newOption.silent) {
|
|
2646
|
+
if (!column) {
|
|
2647
|
+
column = newOption.sortOption || tableHeaderLast.value.find((it) => colKeyGenValue(it) === colKey);
|
|
2648
|
+
}
|
|
2649
|
+
if (column) {
|
|
2650
|
+
emits("sort-change", column, order, toRaw(dataSourceCopy.value), props.sortConfig);
|
|
2651
|
+
} else {
|
|
2652
|
+
console.warn("Can not find column by key:", colKey);
|
|
2653
|
+
}
|
|
2654
|
+
}
|
|
2655
|
+
return dataSourceCopy.value;
|
|
2656
|
+
}
|
|
2657
|
+
function resetSorter() {
|
|
2658
|
+
sortStates.value = [];
|
|
2659
|
+
initDataSource();
|
|
2660
|
+
}
|
|
2661
|
+
function getSortColumns() {
|
|
2662
|
+
return sortStates.value.map((s) => ({ key: s.key || s.dataIndex, order: s.order }));
|
|
2663
|
+
}
|
|
2664
|
+
function dealDefaultSorter() {
|
|
2665
|
+
if (!props.sortConfig.defaultSort) return;
|
|
2666
|
+
const { key, dataIndex, order, silent } = { silent: false, ...props.sortConfig.defaultSort };
|
|
2667
|
+
setSorter(key || dataIndex, order, { force: false, silent });
|
|
2668
|
+
}
|
|
2669
|
+
return [sortStates, sortCol, onColumnSort, setSorter, resetSorter, getSortColumns, dealDefaultSorter, getColumnSortState, sortData];
|
|
2670
|
+
}
|
|
2508
2671
|
const _hoisted_1 = ["tabindex"];
|
|
2509
2672
|
const _hoisted_2 = { class: "stk-table-scroll-container" };
|
|
2510
2673
|
const _hoisted_3 = { key: 0 };
|
|
@@ -2622,14 +2785,6 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
2622
2785
|
const currentSelectedCellKey = ref();
|
|
2623
2786
|
let currentHoverRow = null;
|
|
2624
2787
|
const currentHoverRowKey = ref(null);
|
|
2625
|
-
const sortSwitchOrder = [null, "desc", "asc"];
|
|
2626
|
-
const isMultiSort = computed(() => props.sortConfig.multiSort ?? false);
|
|
2627
|
-
const multiSortLimit = computed(() => props.sortConfig.multiSortLimit ?? 3);
|
|
2628
|
-
const sortStates = ref([]);
|
|
2629
|
-
const sortCol = computed(() => {
|
|
2630
|
-
var _a;
|
|
2631
|
-
return (_a = sortStates.value[0]) == null ? void 0 : _a.dataIndex;
|
|
2632
|
-
});
|
|
2633
2788
|
const [tableHeaders, tableHeadersForCalc, dealColumns] = useTableColumns(props.virtualX, isRelativeMode);
|
|
2634
2789
|
const filterStatus = ref({});
|
|
2635
2790
|
const tableHeaderLast = computed(() => tableHeadersForCalc.value.slice(-1)[0] || []);
|
|
@@ -2700,6 +2855,14 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
2700
2855
|
return (_b = props.experimental) == null ? void 0 : _b.scrollY;
|
|
2701
2856
|
});
|
|
2702
2857
|
const rowKeyGenCache = /* @__PURE__ */ new WeakMap();
|
|
2858
|
+
const [sortStates, sortCol, onColumnSort, setSorter, resetSorter, getSortColumns, dealDefaultSorter, getColumnSortState, sortData] = useSorter(
|
|
2859
|
+
props,
|
|
2860
|
+
emits,
|
|
2861
|
+
colKeyGen,
|
|
2862
|
+
tableHeaderLast,
|
|
2863
|
+
dataSourceCopy,
|
|
2864
|
+
initDataSource
|
|
2865
|
+
);
|
|
2703
2866
|
const [isSRBRActive] = useScrollRowByRow(props, tableContainerRef);
|
|
2704
2867
|
const [onThDragStart, onThDragOver, onThDrop, isHeaderDraggable] = useThDrag(props, emits, colKeyGen);
|
|
2705
2868
|
const [onTrDragStart, onTrDragEnter, onTrDragOver, onTrDrop, onTrDragEnd] = useTrDrag(props, emits, dataSourceCopy);
|
|
@@ -2852,14 +3015,13 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
2852
3015
|
});
|
|
2853
3016
|
function initDataSource(v = props.dataSource, option) {
|
|
2854
3017
|
let dataSourceTemp = v.slice();
|
|
3018
|
+
if (!props.sortRemote || (option == null ? void 0 : option.forceSort)) {
|
|
3019
|
+
dataSourceTemp = sortData(dataSourceTemp);
|
|
3020
|
+
}
|
|
2855
3021
|
if (isTreeData.value) {
|
|
2856
3022
|
dataSourceTemp = flatTreeData(dataSourceTemp);
|
|
2857
3023
|
}
|
|
2858
3024
|
dataSourceTemp = filterDataSource(dataSourceTemp);
|
|
2859
|
-
if ((!props.sortRemote || (option == null ? void 0 : option.forceSort)) && sortStates.value.length) {
|
|
2860
|
-
const sortConfig = { ...DEFAULT_SORT_CONFIG, ...props.sortConfig };
|
|
2861
|
-
dataSourceTemp = execMultiSort(dataSourceTemp, sortConfig);
|
|
2862
|
-
}
|
|
2863
3025
|
dataSourceCopy.value = dataSourceTemp;
|
|
2864
3026
|
}
|
|
2865
3027
|
function setFilter(status, option) {
|
|
@@ -2881,11 +3043,6 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
2881
3043
|
});
|
|
2882
3044
|
});
|
|
2883
3045
|
}
|
|
2884
|
-
function dealDefaultSorter() {
|
|
2885
|
-
if (!props.sortConfig.defaultSort) return;
|
|
2886
|
-
const { key, dataIndex, order, silent } = { silent: false, ...props.sortConfig.defaultSort };
|
|
2887
|
-
setSorter(key || dataIndex, order, { force: false, silent });
|
|
2888
|
-
}
|
|
2889
3046
|
function handleDealColumns() {
|
|
2890
3047
|
dealColumns(props.columns);
|
|
2891
3048
|
}
|
|
@@ -3068,99 +3225,6 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
3068
3225
|
...mergeCellsWrapper(row, col, rowIndex, colIndex)
|
|
3069
3226
|
};
|
|
3070
3227
|
}
|
|
3071
|
-
function getColumnSortState(colKey) {
|
|
3072
|
-
return sortStates.value[getSortStateIndex(colKey)];
|
|
3073
|
-
}
|
|
3074
|
-
function getSortStateIndex(colKey) {
|
|
3075
|
-
return sortStates.value.findIndex((s) => s.key === colKey || s.dataIndex === colKey);
|
|
3076
|
-
}
|
|
3077
|
-
function addOrUpdateSortState(newState, mode) {
|
|
3078
|
-
const existingIndex = sortStates.value.findIndex((s) => s.key === newState.key || s.dataIndex === newState.dataIndex);
|
|
3079
|
-
if (existingIndex >= 0) {
|
|
3080
|
-
sortStates.value.splice(existingIndex, 1);
|
|
3081
|
-
}
|
|
3082
|
-
if (mode && isMultiSort.value) {
|
|
3083
|
-
if (sortStates.value.length >= multiSortLimit.value) {
|
|
3084
|
-
sortStates.value.pop();
|
|
3085
|
-
}
|
|
3086
|
-
sortStates.value.unshift(newState);
|
|
3087
|
-
} else {
|
|
3088
|
-
sortStates.value = [newState];
|
|
3089
|
-
}
|
|
3090
|
-
}
|
|
3091
|
-
function updateSortState(col, colKey) {
|
|
3092
|
-
const existingIndex = getSortStateIndex(colKey);
|
|
3093
|
-
let newOrder;
|
|
3094
|
-
if (existingIndex >= 0) {
|
|
3095
|
-
const currentOrder = sortStates.value[existingIndex].order;
|
|
3096
|
-
const currentIndex = sortSwitchOrder.indexOf(currentOrder);
|
|
3097
|
-
newOrder = sortSwitchOrder[(currentIndex + 1) % 3];
|
|
3098
|
-
if (newOrder === null) {
|
|
3099
|
-
sortStates.value.splice(existingIndex, 1);
|
|
3100
|
-
} else {
|
|
3101
|
-
const updatedState = { ...sortStates.value[existingIndex], order: newOrder };
|
|
3102
|
-
addOrUpdateSortState(updatedState, 1);
|
|
3103
|
-
}
|
|
3104
|
-
} else {
|
|
3105
|
-
newOrder = sortSwitchOrder[1];
|
|
3106
|
-
const newState = {
|
|
3107
|
-
key: colKey,
|
|
3108
|
-
dataIndex: col.dataIndex,
|
|
3109
|
-
sortField: col.sortField,
|
|
3110
|
-
sortType: col.sortType,
|
|
3111
|
-
order: newOrder
|
|
3112
|
-
};
|
|
3113
|
-
addOrUpdateSortState(newState, 1);
|
|
3114
|
-
}
|
|
3115
|
-
return newOrder;
|
|
3116
|
-
}
|
|
3117
|
-
function execMultiSort(dataSource, sortConfig) {
|
|
3118
|
-
let result = dataSource.slice();
|
|
3119
|
-
for (let i = sortStates.value.length - 1; i >= 0; i--) {
|
|
3120
|
-
const state = sortStates.value[i];
|
|
3121
|
-
const col = tableHeaderLast.value.find((c) => state.key && colKeyGen.value(c) === state.key || c.dataIndex === state.dataIndex);
|
|
3122
|
-
if (col && state.order) {
|
|
3123
|
-
const colSortConfig = { ...sortConfig, ...col.sortConfig };
|
|
3124
|
-
result = tableSort(col, state.order, result, colSortConfig);
|
|
3125
|
-
}
|
|
3126
|
-
}
|
|
3127
|
-
return result;
|
|
3128
|
-
}
|
|
3129
|
-
function onColumnSort(col) {
|
|
3130
|
-
if (!col) {
|
|
3131
|
-
console.warn("onColumnSort: not found col:", col);
|
|
3132
|
-
return;
|
|
3133
|
-
}
|
|
3134
|
-
if (!col.sorter) {
|
|
3135
|
-
return;
|
|
3136
|
-
}
|
|
3137
|
-
const colKey = colKeyGen.value(col);
|
|
3138
|
-
let order = updateSortState(col, colKey);
|
|
3139
|
-
let sortConfig = { ...DEFAULT_SORT_CONFIG, ...props.sortConfig, ...col.sortConfig };
|
|
3140
|
-
if (!order && sortConfig.defaultSort) {
|
|
3141
|
-
const defaultColKey = sortConfig.defaultSort.key || sortConfig.defaultSort.dataIndex;
|
|
3142
|
-
if (defaultColKey) {
|
|
3143
|
-
const defaultCol = tableHeaderLast.value.find((item) => colKeyGen.value(item) === defaultColKey);
|
|
3144
|
-
if (defaultCol) {
|
|
3145
|
-
col = defaultCol;
|
|
3146
|
-
order = sortConfig.defaultSort.order;
|
|
3147
|
-
if (order) {
|
|
3148
|
-
addOrUpdateSortState({
|
|
3149
|
-
key: defaultColKey,
|
|
3150
|
-
dataIndex: defaultCol.dataIndex,
|
|
3151
|
-
sortField: defaultCol.sortField,
|
|
3152
|
-
sortType: defaultCol.sortType,
|
|
3153
|
-
order
|
|
3154
|
-
});
|
|
3155
|
-
}
|
|
3156
|
-
}
|
|
3157
|
-
}
|
|
3158
|
-
}
|
|
3159
|
-
if (!props.sortRemote) {
|
|
3160
|
-
initDataSource();
|
|
3161
|
-
}
|
|
3162
|
-
emits("sort-change", col, order, toRaw(dataSourceCopy.value), sortConfig);
|
|
3163
|
-
}
|
|
3164
3228
|
function onRowClick(e) {
|
|
3165
3229
|
var _a, _b;
|
|
3166
3230
|
const rowIndex = getClosestTrIndex(e.target);
|
|
@@ -3300,7 +3364,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
3300
3364
|
const { scrollTop, scrollLeft } = e.target;
|
|
3301
3365
|
const { scrollTop: vScrollTop } = virtualScroll.value;
|
|
3302
3366
|
const { scrollLeft: vScrollLeft } = virtualScrollX.value;
|
|
3303
|
-
const isYScroll = scrollTop !== vScrollTop;
|
|
3367
|
+
const isYScroll = isExperimentalScrollY.value ? false : scrollTop !== vScrollTop;
|
|
3304
3368
|
const isXScroll = scrollLeft !== vScrollLeft;
|
|
3305
3369
|
if (isYScroll) {
|
|
3306
3370
|
updateVirtualScrollY(scrollTop);
|
|
@@ -3408,48 +3472,6 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
3408
3472
|
);
|
|
3409
3473
|
}
|
|
3410
3474
|
}
|
|
3411
|
-
function setSorter(colKey, order, option = {}) {
|
|
3412
|
-
var _a;
|
|
3413
|
-
const newOption = { silent: true, sortOption: null, sort: true, append: false, ...option };
|
|
3414
|
-
const colKeyGenValue = colKeyGen.value;
|
|
3415
|
-
let column;
|
|
3416
|
-
if (order) {
|
|
3417
|
-
column = newOption.sortOption || tableHeaderLast.value.find((it) => colKeyGenValue(it) === colKey);
|
|
3418
|
-
if (column) {
|
|
3419
|
-
const newState = {
|
|
3420
|
-
key: colKey,
|
|
3421
|
-
dataIndex: column.dataIndex,
|
|
3422
|
-
sortField: column.sortField,
|
|
3423
|
-
sortType: column.sortType,
|
|
3424
|
-
order
|
|
3425
|
-
};
|
|
3426
|
-
const mode = newOption.append && isMultiSort.value ? 1 : 0;
|
|
3427
|
-
addOrUpdateSortState(newState, mode);
|
|
3428
|
-
}
|
|
3429
|
-
} else {
|
|
3430
|
-
sortStates.value = [];
|
|
3431
|
-
}
|
|
3432
|
-
if (newOption.sort && ((_a = dataSourceCopy.value) == null ? void 0 : _a.length)) {
|
|
3433
|
-
if (!props.sortRemote || newOption.force) {
|
|
3434
|
-
initDataSource(props.dataSource, { forceSort: newOption.force });
|
|
3435
|
-
}
|
|
3436
|
-
}
|
|
3437
|
-
if (!newOption.silent) {
|
|
3438
|
-
if (!column) {
|
|
3439
|
-
column = newOption.sortOption || tableHeaderLast.value.find((it) => colKeyGenValue(it) === colKey);
|
|
3440
|
-
}
|
|
3441
|
-
if (column) {
|
|
3442
|
-
emits("sort-change", column, order, toRaw(dataSourceCopy.value), props.sortConfig);
|
|
3443
|
-
} else {
|
|
3444
|
-
console.warn("Can not find column by key:", colKey);
|
|
3445
|
-
}
|
|
3446
|
-
}
|
|
3447
|
-
return dataSourceCopy.value;
|
|
3448
|
-
}
|
|
3449
|
-
function resetSorter() {
|
|
3450
|
-
sortStates.value = [];
|
|
3451
|
-
initDataSource();
|
|
3452
|
-
}
|
|
3453
3475
|
function scrollTo(top = 0, left = 0) {
|
|
3454
3476
|
if (!tableContainerRef.value) return;
|
|
3455
3477
|
if (top !== null) tableContainerRef.value.scrollTop = top;
|
|
@@ -3458,9 +3480,6 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
3458
3480
|
function getTableData() {
|
|
3459
3481
|
return toRaw(dataSourceCopy.value);
|
|
3460
3482
|
}
|
|
3461
|
-
function getSortColumns() {
|
|
3462
|
-
return sortStates.value.map((s) => ({ key: s.key || s.dataIndex, order: s.order }));
|
|
3463
|
-
}
|
|
3464
3483
|
__expose({
|
|
3465
3484
|
/**
|
|
3466
3485
|
* 重新计算虚拟列表宽高
|
package/lib/style.css
CHANGED
package/package.json
CHANGED
|
@@ -283,8 +283,6 @@ import {
|
|
|
283
283
|
RowActiveOption,
|
|
284
284
|
SeqConfig,
|
|
285
285
|
SortConfig,
|
|
286
|
-
SortOption,
|
|
287
|
-
SortState,
|
|
288
286
|
StkTableColumn,
|
|
289
287
|
TagType,
|
|
290
288
|
TreeConfig,
|
|
@@ -309,8 +307,9 @@ import { useTrDrag } from './useTrDrag';
|
|
|
309
307
|
import { useTree } from './useTree';
|
|
310
308
|
import { useVirtualScroll } from './useVirtualScroll';
|
|
311
309
|
import { useWheeling } from './useWheeling';
|
|
310
|
+
import { useSorter } from './useSorter';
|
|
312
311
|
import { createStkTableId, getCalculatedColWidth } from './utils/constRefUtils';
|
|
313
|
-
import { getClosestColKey, getClosestTr, getClosestTrIndex,
|
|
312
|
+
import { getClosestColKey, getClosestTr, getClosestTrIndex, rafThrottle, transformWidthToStr } from './utils/index';
|
|
314
313
|
import { useAreaSelection } from './features';
|
|
315
314
|
|
|
316
315
|
/** Generic stands for DataType */
|
|
@@ -730,24 +729,6 @@ const currentHoverRowKey = ref<UniqKey | null>(null);
|
|
|
730
729
|
/** 当前hover的列的key */
|
|
731
730
|
// const currentColHoverKey = ref(null);
|
|
732
731
|
|
|
733
|
-
/** 排序切换顺序 */
|
|
734
|
-
const sortSwitchOrder: Order[] = [null, 'desc', 'asc'] as const;
|
|
735
|
-
|
|
736
|
-
/** 是否启用多列排序 */
|
|
737
|
-
const isMultiSort = computed(() => props.sortConfig.multiSort ?? false);
|
|
738
|
-
|
|
739
|
-
/** 多列排序限制 */
|
|
740
|
-
const multiSortLimit = computed(() => props.sortConfig.multiSortLimit ?? 3);
|
|
741
|
-
|
|
742
|
-
/**
|
|
743
|
-
* 多列排序状态数组
|
|
744
|
-
* 优先级按数组顺序,越靠前优先级越高(先点击的优先级高)
|
|
745
|
-
*/
|
|
746
|
-
const sortStates = ref<SortState<DT>[]>([]);
|
|
747
|
-
|
|
748
|
-
/** 对外暴露:当前排序的列 key(只读计算属性) */
|
|
749
|
-
const sortCol = computed<keyof DT | undefined>(() => sortStates.value[0]?.dataIndex);
|
|
750
|
-
|
|
751
732
|
const [tableHeaders, tableHeadersForCalc, dealColumns] = useTableColumns<DT>(props.virtualX, isRelativeMode);
|
|
752
733
|
|
|
753
734
|
const filterStatus = ref<Record<UniqKey, FilterStatus>>({});
|
|
@@ -834,6 +815,16 @@ const isExperimentalScrollY = computed(() => {
|
|
|
834
815
|
|
|
835
816
|
const rowKeyGenCache = new WeakMap();
|
|
836
817
|
|
|
818
|
+
// 使用 useSorter hook 管理排序逻辑
|
|
819
|
+
const [sortStates, sortCol, onColumnSort, setSorter, resetSorter, getSortColumns, dealDefaultSorter, getColumnSortState, sortData] = useSorter<DT>(
|
|
820
|
+
props,
|
|
821
|
+
emits,
|
|
822
|
+
colKeyGen,
|
|
823
|
+
tableHeaderLast,
|
|
824
|
+
dataSourceCopy,
|
|
825
|
+
initDataSource,
|
|
826
|
+
);
|
|
827
|
+
|
|
837
828
|
const [isSRBRActive] = useScrollRowByRow(props, tableContainerRef);
|
|
838
829
|
|
|
839
830
|
const [onThDragStart, onThDragOver, onThDrop, isHeaderDraggable] = useThDrag(props, emits, colKeyGen);
|
|
@@ -1016,15 +1007,16 @@ onMounted(() => {
|
|
|
1016
1007
|
|
|
1017
1008
|
function initDataSource(v = props.dataSource, option?: { forceSort?: boolean }) {
|
|
1018
1009
|
let dataSourceTemp = v.slice(); // shallow copy
|
|
1010
|
+
|
|
1011
|
+
// 排序(tableSort 内部会根据 sortChildren 自动处理树形递归排序)
|
|
1012
|
+
if (!props.sortRemote || option?.forceSort) {
|
|
1013
|
+
dataSourceTemp = sortData(dataSourceTemp);
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1019
1016
|
if (isTreeData.value) {
|
|
1020
|
-
// only tree data need flat
|
|
1021
1017
|
dataSourceTemp = flatTreeData(dataSourceTemp);
|
|
1022
1018
|
}
|
|
1023
1019
|
dataSourceTemp = filterDataSource(dataSourceTemp);
|
|
1024
|
-
if ((!props.sortRemote || option?.forceSort) && sortStates.value.length) {
|
|
1025
|
-
const sortConfig = { ...DEFAULT_SORT_CONFIG, ...props.sortConfig };
|
|
1026
|
-
dataSourceTemp = execMultiSort(dataSourceTemp, sortConfig);
|
|
1027
|
-
}
|
|
1028
1020
|
dataSourceCopy.value = dataSourceTemp;
|
|
1029
1021
|
}
|
|
1030
1022
|
|
|
@@ -1054,12 +1046,6 @@ function filterDataSource(dataSource: DT[]) {
|
|
|
1054
1046
|
});
|
|
1055
1047
|
}
|
|
1056
1048
|
|
|
1057
|
-
function dealDefaultSorter() {
|
|
1058
|
-
if (!props.sortConfig.defaultSort) return;
|
|
1059
|
-
const { key, dataIndex, order, silent } = { silent: false, ...props.sortConfig.defaultSort };
|
|
1060
|
-
setSorter((key || dataIndex) as string, order, { force: false, silent });
|
|
1061
|
-
}
|
|
1062
|
-
|
|
1063
1049
|
/**
|
|
1064
1050
|
* Wrapper for dealColumns to pass props.columns
|
|
1065
1051
|
*/
|
|
@@ -1277,144 +1263,6 @@ function getTDProps(row: PrivateRowDT | null | undefined, col: StkTableColumn<Pr
|
|
|
1277
1263
|
};
|
|
1278
1264
|
}
|
|
1279
1265
|
|
|
1280
|
-
function getColumnSortState(colKey: UniqKey): SortState<DT> | undefined {
|
|
1281
|
-
return sortStates.value[getSortStateIndex(colKey)];
|
|
1282
|
-
}
|
|
1283
|
-
/**
|
|
1284
|
-
* 获取列的排序状态索引
|
|
1285
|
-
*/
|
|
1286
|
-
function getSortStateIndex(colKey: UniqKey): number {
|
|
1287
|
-
return sortStates.value.findIndex(s => s.key === colKey || s.dataIndex === colKey);
|
|
1288
|
-
}
|
|
1289
|
-
|
|
1290
|
-
/**
|
|
1291
|
-
* 添加或更新排序状态到 sortStates
|
|
1292
|
-
* @param newState 新的排序状态
|
|
1293
|
-
* @param mode '1' - 追加模式(多列排序),0 - 替换模式(单列排序)
|
|
1294
|
-
*/
|
|
1295
|
-
function addOrUpdateSortState(newState: SortState<DT>, mode?: 1 | 0) {
|
|
1296
|
-
const existingIndex = sortStates.value.findIndex(s => s.key === newState.key || s.dataIndex === newState.dataIndex);
|
|
1297
|
-
|
|
1298
|
-
if (existingIndex >= 0) {
|
|
1299
|
-
// 移除已存在的相同列
|
|
1300
|
-
sortStates.value.splice(existingIndex, 1);
|
|
1301
|
-
}
|
|
1302
|
-
|
|
1303
|
-
if (mode && isMultiSort.value) {
|
|
1304
|
-
// 多列排序模式:检查数量限制,然后添加到最前面
|
|
1305
|
-
if (sortStates.value.length >= multiSortLimit.value) {
|
|
1306
|
-
sortStates.value.pop();
|
|
1307
|
-
}
|
|
1308
|
-
sortStates.value.unshift(newState);
|
|
1309
|
-
} else {
|
|
1310
|
-
sortStates.value = [newState];
|
|
1311
|
-
}
|
|
1312
|
-
}
|
|
1313
|
-
|
|
1314
|
-
function updateSortState(col: StkTableColumn<DT>, colKey: UniqKey): Order {
|
|
1315
|
-
const existingIndex = getSortStateIndex(colKey);
|
|
1316
|
-
let newOrder: Order;
|
|
1317
|
-
|
|
1318
|
-
if (existingIndex >= 0) {
|
|
1319
|
-
// 已存在该列的排序,切换排序顺序
|
|
1320
|
-
const currentOrder = sortStates.value[existingIndex].order;
|
|
1321
|
-
const currentIndex = sortSwitchOrder.indexOf(currentOrder);
|
|
1322
|
-
newOrder = sortSwitchOrder[(currentIndex + 1) % 3];
|
|
1323
|
-
|
|
1324
|
-
if (newOrder === null) {
|
|
1325
|
-
// 取消排序,从数组中移除
|
|
1326
|
-
sortStates.value.splice(existingIndex, 1);
|
|
1327
|
-
} else {
|
|
1328
|
-
// 更新排序顺序
|
|
1329
|
-
const updatedState = { ...sortStates.value[existingIndex], order: newOrder };
|
|
1330
|
-
addOrUpdateSortState(updatedState, 1);
|
|
1331
|
-
}
|
|
1332
|
-
} else {
|
|
1333
|
-
newOrder = sortSwitchOrder[1];
|
|
1334
|
-
|
|
1335
|
-
const newState: SortState<DT> = {
|
|
1336
|
-
key: colKey,
|
|
1337
|
-
dataIndex: col.dataIndex,
|
|
1338
|
-
sortField: col.sortField,
|
|
1339
|
-
sortType: col.sortType,
|
|
1340
|
-
order: newOrder,
|
|
1341
|
-
};
|
|
1342
|
-
|
|
1343
|
-
addOrUpdateSortState(newState, 1);
|
|
1344
|
-
}
|
|
1345
|
-
|
|
1346
|
-
return newOrder;
|
|
1347
|
-
}
|
|
1348
|
-
|
|
1349
|
-
/**
|
|
1350
|
-
* 执行多列排序
|
|
1351
|
-
*/
|
|
1352
|
-
function execMultiSort(dataSource: DT[], sortConfig: SortConfig<DT>): DT[] {
|
|
1353
|
-
let result = dataSource.slice();
|
|
1354
|
-
|
|
1355
|
-
// 从后往前排序,这样前面的排序优先级更高
|
|
1356
|
-
for (let i = sortStates.value.length - 1; i >= 0; i--) {
|
|
1357
|
-
const state = sortStates.value[i];
|
|
1358
|
-
const col = tableHeaderLast.value.find(c => (state.key && colKeyGen.value(c) === state.key) || c.dataIndex === state.dataIndex);
|
|
1359
|
-
if (col && state.order) {
|
|
1360
|
-
const colSortConfig = { ...sortConfig, ...col.sortConfig };
|
|
1361
|
-
result = tableSort(col, state.order, result, colSortConfig);
|
|
1362
|
-
}
|
|
1363
|
-
}
|
|
1364
|
-
|
|
1365
|
-
return result;
|
|
1366
|
-
}
|
|
1367
|
-
|
|
1368
|
-
/**
|
|
1369
|
-
* 表头点击排序
|
|
1370
|
-
*
|
|
1371
|
-
* en: Sort a column
|
|
1372
|
-
* @param click 是否为点击表头触发
|
|
1373
|
-
* @param options.force sort-remote 开启后是否强制排序
|
|
1374
|
-
* @param options.emit 是否触发回调
|
|
1375
|
-
*/
|
|
1376
|
-
function onColumnSort(col: StkTableColumn<DT> | undefined | null) {
|
|
1377
|
-
if (!col) {
|
|
1378
|
-
console.warn('onColumnSort: not found col:', col);
|
|
1379
|
-
return;
|
|
1380
|
-
}
|
|
1381
|
-
if (!col.sorter) {
|
|
1382
|
-
// 点击表头触发的排序,如果列没有配置sorter则不处理。setSorter 触发的排序则保持通行。
|
|
1383
|
-
return;
|
|
1384
|
-
}
|
|
1385
|
-
const colKey = colKeyGen.value(col);
|
|
1386
|
-
|
|
1387
|
-
let order = updateSortState(col, colKey);
|
|
1388
|
-
let sortConfig: SortConfig<DT> = { ...DEFAULT_SORT_CONFIG, ...props.sortConfig, ...col.sortConfig };
|
|
1389
|
-
|
|
1390
|
-
// 处理 defaultSort(当取消排序时)
|
|
1391
|
-
if (!order && sortConfig.defaultSort) {
|
|
1392
|
-
const defaultColKey = sortConfig.defaultSort.key || sortConfig.defaultSort.dataIndex;
|
|
1393
|
-
if (defaultColKey) {
|
|
1394
|
-
const defaultCol = tableHeaderLast.value.find(item => colKeyGen.value(item) === defaultColKey);
|
|
1395
|
-
if (defaultCol) {
|
|
1396
|
-
col = defaultCol;
|
|
1397
|
-
order = sortConfig.defaultSort.order;
|
|
1398
|
-
if (order) {
|
|
1399
|
-
addOrUpdateSortState({
|
|
1400
|
-
key: defaultColKey,
|
|
1401
|
-
dataIndex: defaultCol.dataIndex,
|
|
1402
|
-
sortField: defaultCol.sortField,
|
|
1403
|
-
sortType: defaultCol.sortType,
|
|
1404
|
-
order,
|
|
1405
|
-
});
|
|
1406
|
-
}
|
|
1407
|
-
}
|
|
1408
|
-
}
|
|
1409
|
-
}
|
|
1410
|
-
|
|
1411
|
-
if (!props.sortRemote) {
|
|
1412
|
-
initDataSource();
|
|
1413
|
-
}
|
|
1414
|
-
|
|
1415
|
-
emits('sort-change', col, order, toRaw(dataSourceCopy.value), sortConfig);
|
|
1416
|
-
}
|
|
1417
|
-
|
|
1418
1266
|
function onRowClick(e: MouseEvent) {
|
|
1419
1267
|
const rowIndex = getClosestTrIndex(e.target as HTMLElement);
|
|
1420
1268
|
const row = dataSourceCopy.value[rowIndex];
|
|
@@ -1591,7 +1439,9 @@ function onTableScroll(e: Event) {
|
|
|
1591
1439
|
const { scrollTop, scrollLeft } = e.target as HTMLElement;
|
|
1592
1440
|
const { scrollTop: vScrollTop } = virtualScroll.value;
|
|
1593
1441
|
const { scrollLeft: vScrollLeft } = virtualScrollX.value;
|
|
1594
|
-
|
|
1442
|
+
// 在 experimental.scrollY 模式下,纵向滚动通过 transform 模拟,DOM scrollTop 始终为 0,
|
|
1443
|
+
// 不能用来判断纵向滚动,否则横向滚动时会误触发纵向滚动重置
|
|
1444
|
+
const isYScroll = isExperimentalScrollY.value ? false : scrollTop !== vScrollTop;
|
|
1595
1445
|
const isXScroll = scrollLeft !== vScrollLeft;
|
|
1596
1446
|
|
|
1597
1447
|
if (isYScroll) {
|
|
@@ -1713,69 +1563,6 @@ function setSelectedCell(row?: DT, col?: StkTableColumn<DT>, option = { silent:
|
|
|
1713
1563
|
}
|
|
1714
1564
|
}
|
|
1715
1565
|
|
|
1716
|
-
/**
|
|
1717
|
-
* 设置表头排序状态。
|
|
1718
|
-
* @param colKey 列唯一键字段。如果你想要取消排序状态,请使用`resetSorter`
|
|
1719
|
-
* @param order 正序倒序
|
|
1720
|
-
* @param option.sortOption 指定排序参数。同 StkTableColumn 中排序相关字段。建议从columns中find得到。
|
|
1721
|
-
* @param option.sort 是否触发排序-默认true
|
|
1722
|
-
* @param option.silent 是否禁止触发回调-默认true
|
|
1723
|
-
* @param option.force 是否触发排序-默认true
|
|
1724
|
-
* @param option.append 是否追加排序(多列排序模式)。为true时保留现有排序状态,将新排序添加到最前面;为false时替换所有排序状态
|
|
1725
|
-
* @return 表格数据
|
|
1726
|
-
*/
|
|
1727
|
-
function setSorter(
|
|
1728
|
-
colKey: string,
|
|
1729
|
-
order: Order,
|
|
1730
|
-
option: { sortOption?: SortOption<DT>; force?: boolean; silent?: boolean; sort?: boolean; append?: boolean } = {},
|
|
1731
|
-
) {
|
|
1732
|
-
const newOption = { silent: true, sortOption: null, sort: true, append: false, ...option };
|
|
1733
|
-
const colKeyGenValue = colKeyGen.value;
|
|
1734
|
-
let column: StkTableColumn<DT> | undefined;
|
|
1735
|
-
|
|
1736
|
-
if (order) {
|
|
1737
|
-
column = newOption.sortOption || tableHeaderLast.value.find(it => colKeyGenValue(it) === colKey);
|
|
1738
|
-
if (column) {
|
|
1739
|
-
const newState: SortState<DT> = {
|
|
1740
|
-
key: colKey,
|
|
1741
|
-
dataIndex: column.dataIndex,
|
|
1742
|
-
sortField: column.sortField,
|
|
1743
|
-
sortType: column.sortType,
|
|
1744
|
-
order,
|
|
1745
|
-
};
|
|
1746
|
-
|
|
1747
|
-
const mode = newOption.append && isMultiSort.value ? 1 : 0;
|
|
1748
|
-
addOrUpdateSortState(newState, mode);
|
|
1749
|
-
}
|
|
1750
|
-
} else {
|
|
1751
|
-
sortStates.value = [];
|
|
1752
|
-
}
|
|
1753
|
-
|
|
1754
|
-
if (newOption.sort && dataSourceCopy.value?.length) {
|
|
1755
|
-
if (!props.sortRemote || newOption.force) {
|
|
1756
|
-
initDataSource(props.dataSource, { forceSort: newOption.force });
|
|
1757
|
-
}
|
|
1758
|
-
}
|
|
1759
|
-
|
|
1760
|
-
if (!newOption.silent) {
|
|
1761
|
-
if (!column) {
|
|
1762
|
-
column = newOption.sortOption || tableHeaderLast.value.find(it => colKeyGenValue(it) === colKey);
|
|
1763
|
-
}
|
|
1764
|
-
if (column) {
|
|
1765
|
-
emits('sort-change', column, order, toRaw(dataSourceCopy.value), props.sortConfig);
|
|
1766
|
-
} else {
|
|
1767
|
-
console.warn('Can not find column by key:', colKey);
|
|
1768
|
-
}
|
|
1769
|
-
}
|
|
1770
|
-
|
|
1771
|
-
return dataSourceCopy.value;
|
|
1772
|
-
}
|
|
1773
|
-
|
|
1774
|
-
function resetSorter() {
|
|
1775
|
-
sortStates.value = [];
|
|
1776
|
-
initDataSource();
|
|
1777
|
-
}
|
|
1778
|
-
|
|
1779
1566
|
/**
|
|
1780
1567
|
* set scroll bar position
|
|
1781
1568
|
* @param top null to not change
|
|
@@ -1792,14 +1579,6 @@ function getTableData() {
|
|
|
1792
1579
|
return toRaw(dataSourceCopy.value);
|
|
1793
1580
|
}
|
|
1794
1581
|
|
|
1795
|
-
/**
|
|
1796
|
-
* get current sort info
|
|
1797
|
-
* @return {{key:string,order:Order}[]}
|
|
1798
|
-
*/
|
|
1799
|
-
function getSortColumns(): { key: keyof DT | undefined; order: Order }[] {
|
|
1800
|
-
return sortStates.value.map(s => ({ key: s.key || s.dataIndex, order: s.order }));
|
|
1801
|
-
}
|
|
1802
|
-
|
|
1803
1582
|
defineExpose({
|
|
1804
1583
|
/**
|
|
1805
1584
|
* 重新计算虚拟列表宽高
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import { computed, ref, toRaw, type Ref } from 'vue';
|
|
2
|
+
import { DEFAULT_SORT_CONFIG } from './const';
|
|
3
|
+
import type { Order, SortConfig, SortOption, SortState, StkTableColumn, UniqKey } from './types/index';
|
|
4
|
+
import { tableSort } from './utils/index';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 排序切换顺序
|
|
8
|
+
*/
|
|
9
|
+
const SORT_SWITCH_ORDER: Order[] = [null, 'desc', 'asc'] as const;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 排序 Hook
|
|
13
|
+
* 管理表格排序状态和相关操作
|
|
14
|
+
* @param props 表格 props
|
|
15
|
+
* @param colKeyGen 列 key 生成函数
|
|
16
|
+
* @param tableHeaderLast 表头最后一行(叶子节点)
|
|
17
|
+
* @param dataSourceCopy 数据源副本 ref
|
|
18
|
+
* @param initDataSource 初始化数据源函数
|
|
19
|
+
* @param emits 事件发射函数
|
|
20
|
+
* @returns 排序相关状态和方法
|
|
21
|
+
*/
|
|
22
|
+
export function useSorter<DT extends Record<string, any>>(
|
|
23
|
+
props: any,
|
|
24
|
+
emits: any,
|
|
25
|
+
colKeyGen: Ref<(col: StkTableColumn<DT>) => string>,
|
|
26
|
+
tableHeaderLast: Ref<StkTableColumn<DT>[]>,
|
|
27
|
+
dataSourceCopy: Ref<DT[]>,
|
|
28
|
+
initDataSource: (data?: DT[], option?: { forceSort?: boolean }) => void,
|
|
29
|
+
) {
|
|
30
|
+
/** 多列排序状态数组 */
|
|
31
|
+
const sortStates = ref<SortState<DT>[]>([]);
|
|
32
|
+
|
|
33
|
+
/** 是否启用多列排序 */
|
|
34
|
+
const isMultiSort = computed(() => props.sortConfig.multiSort ?? false);
|
|
35
|
+
|
|
36
|
+
/** 多列排序限制 */
|
|
37
|
+
const multiSortLimit = computed(() => props.sortConfig.multiSortLimit ?? 3);
|
|
38
|
+
|
|
39
|
+
/** 对外暴露:当前排序的列 key(只读计算属性) */
|
|
40
|
+
const sortCol = computed<keyof DT | undefined>(() => sortStates.value[0]?.dataIndex);
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* 获取列的排序状态
|
|
44
|
+
*/
|
|
45
|
+
function getColumnSortState(colKey: UniqKey): SortState<DT> | undefined {
|
|
46
|
+
return sortStates.value[getSortStateIndex(colKey)] as SortState<DT> | undefined;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* 获取列的排序状态索引
|
|
51
|
+
*/
|
|
52
|
+
function getSortStateIndex(colKey: UniqKey): number {
|
|
53
|
+
return sortStates.value.findIndex(s => s.key === colKey || s.dataIndex === colKey);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* 添加或更新排序状态到 sortStates
|
|
58
|
+
* @param newState 新的排序状态
|
|
59
|
+
* @param mode '1' - 追加模式(多列排序),0 - 替换模式(单列排序)
|
|
60
|
+
*/
|
|
61
|
+
function addOrUpdateSortState(newState: SortState<DT>, mode?: 1 | 0) {
|
|
62
|
+
const existingIndex = sortStates.value.findIndex(s => s.key === newState.key || s.dataIndex === newState.dataIndex);
|
|
63
|
+
|
|
64
|
+
if (existingIndex >= 0) {
|
|
65
|
+
// 移除已存在的相同列
|
|
66
|
+
sortStates.value.splice(existingIndex, 1);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (mode && isMultiSort.value) {
|
|
70
|
+
// 多列排序模式:检查数量限制,然后添加到最前面
|
|
71
|
+
if (sortStates.value.length >= multiSortLimit.value) {
|
|
72
|
+
sortStates.value.pop();
|
|
73
|
+
}
|
|
74
|
+
sortStates.value.unshift(newState as any);
|
|
75
|
+
} else {
|
|
76
|
+
sortStates.value = [newState as any];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* 更新排序状态(点击表头时调用)
|
|
82
|
+
*/
|
|
83
|
+
function updateSortState(col: StkTableColumn<DT>, colKey: UniqKey): Order {
|
|
84
|
+
const existingIndex = getSortStateIndex(colKey);
|
|
85
|
+
let newOrder: Order;
|
|
86
|
+
|
|
87
|
+
if (existingIndex >= 0) {
|
|
88
|
+
// 已存在该列的排序,切换排序顺序
|
|
89
|
+
const currentOrder = sortStates.value[existingIndex].order;
|
|
90
|
+
const currentIndex = SORT_SWITCH_ORDER.indexOf(currentOrder);
|
|
91
|
+
newOrder = SORT_SWITCH_ORDER[(currentIndex + 1) % 3];
|
|
92
|
+
|
|
93
|
+
if (newOrder === null) {
|
|
94
|
+
// 取消排序,从数组中移除
|
|
95
|
+
sortStates.value.splice(existingIndex, 1);
|
|
96
|
+
} else {
|
|
97
|
+
// 更新排序顺序
|
|
98
|
+
const updatedState = { ...sortStates.value[existingIndex], order: newOrder };
|
|
99
|
+
addOrUpdateSortState(updatedState as any, 1);
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
newOrder = SORT_SWITCH_ORDER[1];
|
|
103
|
+
|
|
104
|
+
const newState: SortState<DT> = {
|
|
105
|
+
key: colKey,
|
|
106
|
+
dataIndex: col.dataIndex,
|
|
107
|
+
sortField: col.sortField,
|
|
108
|
+
sortType: col.sortType,
|
|
109
|
+
order: newOrder,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
addOrUpdateSortState(newState, 1);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return newOrder;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* 对数据源执行排序
|
|
120
|
+
* tableSort 内部会根据 sortChildren 配置自动处理树形递归排序
|
|
121
|
+
*/
|
|
122
|
+
function sortData(dataSource: DT[]): DT[] {
|
|
123
|
+
if (!sortStates.value.length) return dataSource;
|
|
124
|
+
|
|
125
|
+
const sortConfig = { ...DEFAULT_SORT_CONFIG, ...props.sortConfig };
|
|
126
|
+
let result = dataSource.slice();
|
|
127
|
+
|
|
128
|
+
// 从后往前排序,这样前面的排序优先级更高
|
|
129
|
+
for (let i = sortStates.value.length - 1; i >= 0; i--) {
|
|
130
|
+
const state = sortStates.value[i];
|
|
131
|
+
const col = tableHeaderLast.value.find(c => (state.key && colKeyGen.value(c) === state.key) || c.dataIndex === state.dataIndex);
|
|
132
|
+
if (col && state.order) {
|
|
133
|
+
const colSortConfig = { ...sortConfig, ...col.sortConfig };
|
|
134
|
+
result = tableSort(col, state.order, result, colSortConfig);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return result;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* 表头点击排序
|
|
143
|
+
*/
|
|
144
|
+
function onColumnSort(col: StkTableColumn<DT> | undefined | null) {
|
|
145
|
+
if (!col) {
|
|
146
|
+
console.warn('onColumnSort: not found col:', col);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
if (!col.sorter) {
|
|
150
|
+
// 点击表头触发的排序,如果列没有配置sorter则不处理。setSorter 触发的排序则保持通行。
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
const colKey = colKeyGen.value(col);
|
|
154
|
+
|
|
155
|
+
let order = updateSortState(col, colKey);
|
|
156
|
+
const sortConfig: SortConfig<DT> = { ...DEFAULT_SORT_CONFIG, ...props.sortConfig, ...col.sortConfig };
|
|
157
|
+
|
|
158
|
+
// 处理 defaultSort(当取消排序时)
|
|
159
|
+
if (!order && sortConfig.defaultSort) {
|
|
160
|
+
const defaultColKey = sortConfig.defaultSort.key || sortConfig.defaultSort.dataIndex;
|
|
161
|
+
if (defaultColKey) {
|
|
162
|
+
const defaultCol = tableHeaderLast.value.find(item => colKeyGen.value(item) === defaultColKey);
|
|
163
|
+
if (defaultCol) {
|
|
164
|
+
col = defaultCol;
|
|
165
|
+
order = sortConfig.defaultSort.order;
|
|
166
|
+
if (order) {
|
|
167
|
+
addOrUpdateSortState({
|
|
168
|
+
key: defaultColKey,
|
|
169
|
+
dataIndex: defaultCol.dataIndex,
|
|
170
|
+
sortField: defaultCol.sortField,
|
|
171
|
+
sortType: defaultCol.sortType,
|
|
172
|
+
order,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (!props.sortRemote) {
|
|
180
|
+
initDataSource();
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
emits('sort-change', col, order, toRaw(dataSourceCopy.value), sortConfig);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* 设置表头排序状态
|
|
188
|
+
*/
|
|
189
|
+
function setSorter(
|
|
190
|
+
colKey: string,
|
|
191
|
+
order: Order,
|
|
192
|
+
option: { sortOption?: SortOption<DT>; force?: boolean; silent?: boolean; sort?: boolean; append?: boolean } = {},
|
|
193
|
+
): DT[] {
|
|
194
|
+
const newOption = { silent: true, sortOption: null, sort: true, append: false, ...option };
|
|
195
|
+
const colKeyGenValue = colKeyGen.value;
|
|
196
|
+
let column: StkTableColumn<DT> | undefined;
|
|
197
|
+
|
|
198
|
+
if (order) {
|
|
199
|
+
column = newOption.sortOption || tableHeaderLast.value.find(it => colKeyGenValue(it) === colKey);
|
|
200
|
+
if (column) {
|
|
201
|
+
const newState: SortState<DT> = {
|
|
202
|
+
key: colKey,
|
|
203
|
+
dataIndex: column.dataIndex,
|
|
204
|
+
sortField: column.sortField,
|
|
205
|
+
sortType: column.sortType,
|
|
206
|
+
order,
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
const mode = newOption.append && isMultiSort.value ? 1 : 0;
|
|
210
|
+
addOrUpdateSortState(newState, mode);
|
|
211
|
+
}
|
|
212
|
+
} else {
|
|
213
|
+
sortStates.value = [];
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (newOption.sort && dataSourceCopy.value?.length) {
|
|
217
|
+
if (!props.sortRemote || newOption.force) {
|
|
218
|
+
initDataSource(props.dataSource, { forceSort: newOption.force });
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (!newOption.silent) {
|
|
223
|
+
if (!column) {
|
|
224
|
+
column = newOption.sortOption || tableHeaderLast.value.find(it => colKeyGenValue(it) === colKey);
|
|
225
|
+
}
|
|
226
|
+
if (column) {
|
|
227
|
+
emits('sort-change', column, order, toRaw(dataSourceCopy.value), props.sortConfig);
|
|
228
|
+
} else {
|
|
229
|
+
console.warn('Can not find column by key:', colKey);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return dataSourceCopy.value;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* 重置排序器
|
|
238
|
+
*/
|
|
239
|
+
function resetSorter() {
|
|
240
|
+
sortStates.value = [];
|
|
241
|
+
initDataSource();
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* 获取排序列信息
|
|
246
|
+
*/
|
|
247
|
+
function getSortColumns(): { key: keyof DT | undefined; order: Order }[] {
|
|
248
|
+
return sortStates.value.map(s => ({ key: s.key || s.dataIndex, order: s.order }));
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* 处理默认排序
|
|
253
|
+
*/
|
|
254
|
+
function dealDefaultSorter() {
|
|
255
|
+
if (!props.sortConfig.defaultSort) return;
|
|
256
|
+
const { key, dataIndex, order, silent } = { silent: false, ...props.sortConfig.defaultSort };
|
|
257
|
+
setSorter((key || dataIndex) as string, order, { force: false, silent });
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// 只返回需要在组件外部使用的方法和状态
|
|
261
|
+
return [sortStates, sortCol, onColumnSort, setSorter, resetSorter, getSortColumns, dealDefaultSorter, getColumnSortState, sortData] as const;
|
|
262
|
+
}
|
|
@@ -212,7 +212,7 @@ export function useVirtualScroll<DT extends Record<string, any>>(
|
|
|
212
212
|
const headerToBodyRowHeightCount = Math.floor(tableHeaderHeight.value / rowHeight);
|
|
213
213
|
pageSize -= headerToBodyRowHeightCount; //减去表头行数
|
|
214
214
|
}
|
|
215
|
-
const maxScrollTop = dataSourceCopy.value.length * rowHeight + tableHeaderHeight.value - containerHeight;
|
|
215
|
+
const maxScrollTop = Math.max(0, dataSourceCopy.value.length * rowHeight + tableHeaderHeight.value - containerHeight);
|
|
216
216
|
if (scrollTop > maxScrollTop) {
|
|
217
217
|
/** fix: 滚动条不在顶部时,表格数据变少,导致滚动条位置有误 */
|
|
218
218
|
scrollTop = maxScrollTop;
|
|
@@ -272,7 +272,11 @@ export function useVirtualScroll<DT extends Record<string, any>>(
|
|
|
272
272
|
const dataLength = dataSourceCopyTemp.length;
|
|
273
273
|
const rowHeight = getRowHeightFn.value();
|
|
274
274
|
|
|
275
|
-
const vsValue: any = {
|
|
275
|
+
const vsValue: any = {
|
|
276
|
+
startIndex: 0, // github #34 init
|
|
277
|
+
endIndex: dataLength, // github #34 init
|
|
278
|
+
offsetTop: 0, // github #34 init
|
|
279
|
+
};
|
|
276
280
|
const scrollHeight = dataLength * rowHeight + tableHeaderHeight.value;
|
|
277
281
|
const { enabled: scrollbarEnable } = scrollbarOptions.value;
|
|
278
282
|
if (scrollbarEnable) {
|