stk-table-vue 0.2.1 → 0.2.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stk-table-vue",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Simple realtime virtual table for vue3&vue2.7",
5
5
  "main": "./lib/stk-table-vue.js",
6
6
  "types": "./lib/StkTable/index.d.ts",
@@ -191,7 +191,7 @@
191
191
  */
192
192
  import { CSSProperties, onMounted, ref, shallowRef, toRaw, watch } from 'vue';
193
193
  import { Default_Row_Height } from './const';
194
- import { Order, SortOption, SortState, StkTableColumn, UniqKey } from './types/index';
194
+ import { Order, SortConfig, SortOption, SortState, StkTableColumn, UniqKey } from './types/index';
195
195
  import { useAutoResize } from './useAutoResize';
196
196
  import { useColResize } from './useColResize';
197
197
  import { useFixedCol } from './useFixedCol';
@@ -285,6 +285,8 @@ const props = withDefaults(
285
285
  fixedColShadow?: boolean;
286
286
  /** 优化vue2 滚动 */
287
287
  optimizeVue2Scroll?: boolean;
288
+ /** 排序配置 */
289
+ sortConfig?: SortConfig;
288
290
  }>(),
289
291
  {
290
292
  width: '',
@@ -317,6 +319,9 @@ const props = withDefaults(
317
319
  autoResize: true,
318
320
  fixedColShadow: false,
319
321
  optimizeVue2Scroll: false,
322
+ sortConfig: () => ({
323
+ emptyToBottom: false,
324
+ }),
320
325
  },
321
326
  );
322
327
 
@@ -325,7 +330,7 @@ const emits = defineEmits<{
325
330
  * 排序变更触发
326
331
  * ```(col: StkTableColumn<DT>, order: Order, data: DT[])```
327
332
  */
328
- (e: 'sort-change', col: StkTableColumn<DT>, order: Order, data: DT[]): void;
333
+ (e: 'sort-change', col: StkTableColumn<DT>, order: Order, data: DT[], sortConfig: SortConfig): void;
329
334
  /**
330
335
  * 一行点击事件
331
336
  * ```(ev: MouseEvent, row: DT)```
@@ -690,13 +695,13 @@ function onColumnSort(col?: StkTableColumn<any>, click = true, options: { force?
690
695
  sortOrderIndex.value = sortOrderIndex.value % 3;
691
696
 
692
697
  const order = sortSwitchOrder[sortOrderIndex.value];
693
-
698
+ const sortConfig = props.sortConfig;
694
699
  if (!props.sortRemote || options.force) {
695
- dataSourceCopy.value = tableSort(col, order, props.dataSource);
700
+ dataSourceCopy.value = tableSort(col, order, props.dataSource, sortConfig);
696
701
  }
697
702
  // 只有点击才触发事件
698
703
  if (click || options.emit) {
699
- emits('sort-change', col, order, toRaw(dataSourceCopy.value));
704
+ emits('sort-change', col, order, toRaw(dataSourceCopy.value), sortConfig);
700
705
  }
701
706
  }
702
707
 
@@ -68,3 +68,9 @@ export type SortState<T> = {
68
68
  };
69
69
 
70
70
  export type UniqKey = string | ((param: any) => string);
71
+
72
+ /** 排序配置 */
73
+ export type SortConfig = {
74
+ /** 空值始终排在列表末尾 */
75
+ emptyToBottom?: boolean;
76
+ };
@@ -1,5 +1,5 @@
1
1
  import { Default_Col_Width } from './const';
2
- import { Order, SortOption, SortState, StkTableColumn } from './types';
2
+ import { Order, SortConfig, SortOption, SortState, StkTableColumn } from './types';
3
3
 
4
4
  /**
5
5
  * 对有序数组插入新数据
@@ -63,6 +63,34 @@ function strCompare(a: string, b: string, type: 'number' | 'string'): number {
63
63
  }
64
64
  }
65
65
 
66
+ /**
67
+ * 分离出空数据和非空数据成两个数组
68
+ * @param sortOption
69
+ * @param targetDataSource
70
+ * @param isNumber 1 数组
71
+ * @return [值数组,空数组]
72
+ */
73
+ function separatedData(sortOption: SortOption, targetDataSource: any[], isNumber?: boolean) {
74
+ const emptyArr: any[] = [];
75
+ const valueArr: any[] = [];
76
+
77
+ for (let i = 0; i < targetDataSource.length; i++) {
78
+ const row = targetDataSource[i];
79
+ const sortField = sortOption.sortField || sortOption.dataIndex;
80
+ let isEmpty = row[sortField] === null || row[sortField] === '';
81
+ if (isNumber) {
82
+ isEmpty ||= typeof row[sortField] === 'boolean' || Number.isNaN(+row[sortField]);
83
+ }
84
+
85
+ if (isEmpty) {
86
+ emptyArr.push(row);
87
+ } else {
88
+ valueArr.push(row);
89
+ }
90
+ }
91
+ return [valueArr, emptyArr] as const;
92
+ }
93
+
66
94
  /**
67
95
  * 表格排序抽离
68
96
  * 可以在组件外部自己实现表格排序,组件配置remote,使表格不排序。
@@ -72,9 +100,11 @@ function strCompare(a: string, b: string, type: 'number' | 'string'): number {
72
100
  * @param order 排序方式
73
101
  * @param dataSource 排序的数组
74
102
  */
75
- export function tableSort(sortOption: SortOption, order: Order, dataSource: any[]): any[] {
103
+ export function tableSort(sortOption: SortOption, order: Order, dataSource: any[], sortConfig: SortConfig = {}): any[] {
76
104
  if (!dataSource?.length) return dataSource || [];
105
+ sortConfig = Object.assign({ emptyToBottom: false } as SortConfig, sortConfig);
77
106
  let targetDataSource = [...dataSource];
107
+
78
108
  if (typeof sortOption.sorter === 'function') {
79
109
  const customSorterData = sortOption.sorter(targetDataSource, { order, column: sortOption });
80
110
  if (customSorterData) targetDataSource = customSorterData;
@@ -83,36 +113,32 @@ export function tableSort(sortOption: SortOption, order: Order, dataSource: any[
83
113
  let { sortType } = sortOption;
84
114
  if (!sortType) sortType = typeof dataSource[0][sortField] as 'number' | 'string';
85
115
 
116
+ const [valueArr, emptyArr] = separatedData(sortOption, targetDataSource, sortType === 'number');
117
+
86
118
  if (sortType === 'number') {
87
119
  // 按数字类型排序
88
- const nanArr: any[] = []; // 非数字
89
- const numArr: any[] = []; // 数字
90
-
91
- for (let i = 0; i < targetDataSource.length; i++) {
92
- const row = targetDataSource[i];
93
- if (row[sortField] === null || row[sortField] === '' || typeof row[sortField] === 'boolean' || Number.isNaN(+row[sortField])) {
94
- nanArr.push(row);
95
- } else {
96
- numArr.push(row);
97
- }
98
- }
99
120
  // 非数字当作最小值处理
100
121
  if (order === 'asc') {
101
- numArr.sort((a, b) => +a[sortField] - +b[sortField]);
102
- targetDataSource = [...nanArr, ...numArr];
122
+ valueArr.sort((a, b) => +a[sortField] - +b[sortField]);
123
+ targetDataSource = [...emptyArr, ...valueArr];
103
124
  } else {
104
- numArr.sort((a, b) => +b[sortField] - +a[sortField]);
105
- targetDataSource = [...numArr, ...nanArr];
125
+ valueArr.sort((a, b) => +b[sortField] - +a[sortField]);
126
+ targetDataSource = [...valueArr, ...emptyArr];
106
127
  }
107
- // targetDataSource = [...numArr, ...nanArr]; // 非数字不进入排序,一直排在最后
108
128
  } else {
109
129
  // 按string 排序
110
130
  if (order === 'asc') {
111
- targetDataSource.sort((a, b) => String(a[sortField]).localeCompare(b[sortField]));
131
+ valueArr.sort((a, b) => String(a[sortField]).localeCompare(b[sortField]));
132
+ targetDataSource = [...emptyArr, ...valueArr];
112
133
  } else {
113
- targetDataSource.sort((a, b) => String(a[sortField]).localeCompare(b[sortField]) * -1);
134
+ valueArr.sort((a, b) => String(a[sortField]).localeCompare(b[sortField]) * -1);
135
+ targetDataSource = [...valueArr, ...emptyArr];
114
136
  }
115
137
  }
138
+
139
+ if (sortConfig.emptyToBottom) {
140
+ targetDataSource = [...valueArr, ...emptyArr];
141
+ }
116
142
  }
117
143
  return targetDataSource;
118
144
  }