stk-table-vue 0.2.1 → 0.2.3

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.3",
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",
@@ -148,7 +148,7 @@
148
148
  [rowClassName(row, i)]: true,
149
149
  }"
150
150
  :style="{
151
- backgroundColor: row._bgc,
151
+ backgroundColor: highlightRowStore[rowKeyGen(row)]?.bgc,
152
152
  }"
153
153
  @click="e => onRowClick(e, row)"
154
154
  @dblclick="e => onRowDblclick(e, row)"
@@ -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, UniqKeyProp } from './types/index';
195
195
  import { useAutoResize } from './useAutoResize';
196
196
  import { useColResize } from './useColResize';
197
197
  import { useFixedCol } from './useFixedCol';
@@ -235,9 +235,9 @@ const props = withDefaults(
235
235
  /** 表格数据源 */
236
236
  dataSource?: DT[];
237
237
  /** 行唯一键 */
238
- rowKey?: UniqKey;
238
+ rowKey?: UniqKeyProp;
239
239
  /** 列唯一键 */
240
- colKey?: UniqKey;
240
+ colKey?: UniqKeyProp;
241
241
  /** 空值展示文字 */
242
242
  emptyCellText?: string;
243
243
  /** 暂无数据兜底高度是否撑满 */
@@ -285,6 +285,8 @@ const props = withDefaults(
285
285
  fixedColShadow?: boolean;
286
286
  /** 优化vue2 滚动 */
287
287
  optimizeVue2Scroll?: boolean;
288
+ /** 排序配置 */
289
+ sortConfig?: SortConfig<DT>;
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<DT>): void;
329
334
  /**
330
335
  * 一行点击事件
331
336
  * ```(ev: MouseEvent, row: DT)```
@@ -479,7 +484,7 @@ const { getFixedStyle } = useFixedStyle({
479
484
  /**
480
485
  * 高亮行,高亮单元格
481
486
  */
482
- const { setHighlightDimCell, setHighlightDimRow } = useHighlight({ props, tableContainer, rowKeyGen });
487
+ const { highlightRowStore, setHighlightDimCell, setHighlightDimRow } = useHighlight({ props, tableContainer });
483
488
 
484
489
  if (props.autoResize) {
485
490
  useAutoResize({ tableContainer, initVirtualScroll, props, debounceMs: 200 });
@@ -543,8 +548,16 @@ watch(() => props.fixedColShadow, dealFixedColShadow);
543
548
  onMounted(() => {
544
549
  initVirtualScroll();
545
550
  updateFixedShadow();
551
+ dealDefaultSorter();
546
552
  });
547
553
 
554
+ /** 处理默认排序 */
555
+ function dealDefaultSorter() {
556
+ if (!props.sortConfig.defaultSort) return;
557
+ const { dataIndex, order } = props.sortConfig.defaultSort;
558
+ setSorter(dataIndex as string, order);
559
+ }
560
+
548
561
  /**
549
562
  * 处理多级表头
550
563
  */
@@ -554,7 +567,7 @@ function dealColumns() {
554
567
  tableHeaderLast.value = [];
555
568
  const copyColumn = props.columns; // do not deep clone
556
569
  const deep = howDeepTheHeader(copyColumn);
557
- const tempHeaderLast: StkTableColumn<any>[] = [];
570
+ const tempHeaderLast: StkTableColumn<DT>[] = [];
558
571
 
559
572
  if (deep > 1 && props.virtualX) {
560
573
  console.error('多级表头不支持横向虚拟滚动');
@@ -632,7 +645,7 @@ function colKeyGen(col: StkTableColumn<DT>) {
632
645
  }
633
646
 
634
647
  /** 获取列宽度样式 */
635
- function getColWidthStyle(col: StkTableColumn<any>) {
648
+ function getColWidthStyle(col: StkTableColumn<DT>) {
636
649
  const style: CSSProperties = {
637
650
  width: col.width,
638
651
  minWidth: col.minWidth,
@@ -657,7 +670,7 @@ function getColWidthStyle(col: StkTableColumn<any>) {
657
670
  * @param col
658
671
  * @param depth 表头层级
659
672
  */
660
- function getCellStyle(tagType: 1 | 2, col: StkTableColumn<any>, depth?: number): CSSProperties {
673
+ function getCellStyle(tagType: 1 | 2, col: StkTableColumn<DT>, depth?: number): CSSProperties {
661
674
  const style: CSSProperties = {
662
675
  ...getColWidthStyle(col),
663
676
  ...getFixedStyle(tagType, col, depth),
@@ -675,10 +688,11 @@ function getCellStyle(tagType: 1 | 2, col: StkTableColumn<any>, depth?: number):
675
688
 
676
689
  /**
677
690
  * 表头点击排序
678
- * @param {boolean} options.force sort-remote 开启后是否强制排序
679
- * @param {boolean} options.emit 是否触发回调
691
+ * @param click 是否为点击表头触发
692
+ * @param options.force sort-remote 开启后是否强制排序
693
+ * @param options.emit 是否触发回调
680
694
  */
681
- function onColumnSort(col?: StkTableColumn<any>, click = true, options: { force?: boolean; emit?: boolean } = {}) {
695
+ function onColumnSort(col?: StkTableColumn<DT>, click = true, options: { force?: boolean; emit?: boolean } = {}) {
682
696
  if (!col?.sorter) return;
683
697
  options = { force: false, emit: false, ...options };
684
698
  if (sortCol.value !== col.dataIndex) {
@@ -689,14 +703,22 @@ function onColumnSort(col?: StkTableColumn<any>, click = true, options: { force?
689
703
  if (click) sortOrderIndex.value++;
690
704
  sortOrderIndex.value = sortOrderIndex.value % 3;
691
705
 
692
- const order = sortSwitchOrder[sortOrderIndex.value];
706
+ let order = sortSwitchOrder[sortOrderIndex.value];
707
+ const sortConfig = props.sortConfig;
708
+ const defaultSort = sortConfig.defaultSort;
693
709
 
710
+ if (!order && defaultSort) {
711
+ // 没有排序时变成默认排序
712
+ order = defaultSort.order;
713
+ sortOrderIndex.value = sortSwitchOrder.indexOf(order);
714
+ sortCol.value = defaultSort.dataIndex as string;
715
+ }
694
716
  if (!props.sortRemote || options.force) {
695
- dataSourceCopy.value = tableSort(col, order, props.dataSource);
717
+ dataSourceCopy.value = tableSort(col, order, props.dataSource, sortConfig);
696
718
  }
697
719
  // 只有点击才触发事件
698
720
  if (click || options.emit) {
699
- emits('sort-change', col, order, toRaw(dataSourceCopy.value));
721
+ emits('sort-change', col, order, toRaw(dataSourceCopy.value), sortConfig);
700
722
  }
701
723
  }
702
724
 
@@ -808,16 +830,16 @@ function setCurrentRow(rowKey: string, option = { silent: false }) {
808
830
 
809
831
  /**
810
832
  * 设置表头排序状态
811
- * @param {string} dataIndex 列字段
812
- * @param {'asc'|'desc'|null} order
813
- * @param {object} option.sortOption 指定排序参数
814
- * @param {boolean} option.sort 是否触发排序
815
- * @param {boolean} option.silent 是否触发回调
833
+ * @param dataIndex 列字段
834
+ * @param order 正序倒序
835
+ * @param option.sortOption 指定排序参数
836
+ * @param option.sort 是否触发排序-默认true
837
+ * @param option.silent 是否禁止触发回调-默认true
816
838
  */
817
- function setSorter(dataIndex: string, order: null | 'asc' | 'desc', option: { sortOption?: SortOption; silent?: boolean; sort?: boolean } = {}) {
839
+ function setSorter(dataIndex: string, order: Order, option: { sortOption?: SortOption<DT>; silent?: boolean; sort?: boolean } = {}) {
818
840
  const newOption = { silent: true, sortOption: null, sort: true, ...option };
819
841
  sortCol.value = dataIndex;
820
- sortOrderIndex.value = sortSwitchOrder.findIndex(it => it === order);
842
+ sortOrderIndex.value = sortSwitchOrder.indexOf(order);
821
843
 
822
844
  if (newOption.sort && dataSourceCopy.value?.length) {
823
845
  // 如果表格有数据,则进行排序
@@ -59,12 +59,27 @@ export type StkTableColumn<T extends Record<string, any>> = {
59
59
  __PARENT__?: StkTableColumn<T> | null;
60
60
  };
61
61
 
62
- export type SortOption = Pick<StkTableColumn<any>, 'sorter' | 'dataIndex' | 'sortField' | 'sortType'>;
62
+ export type SortOption<T extends Record<string, any>> = Pick<StkTableColumn<T>, 'sorter' | 'dataIndex' | 'sortField' | 'sortType'>;
63
63
 
64
+ /** 排序状态 */
64
65
  export type SortState<T> = {
65
66
  dataIndex: T;
66
67
  order: null | 'asc' | 'desc';
67
68
  sortType?: 'number' | 'string';
68
69
  };
69
70
 
70
- export type UniqKey = string | ((param: any) => string);
71
+ /** 唯一键 */
72
+ export type UniqKey = string | number;
73
+ export type UniqKeyFun = (param: any) => UniqKey;
74
+ export type UniqKeyProp = UniqKey | UniqKeyFun;
75
+
76
+ /** 排序配置 */
77
+ export type SortConfig<T extends Record<string, any>> = {
78
+ /** 空值始终排在列表末尾 */
79
+ emptyToBottom?: boolean;
80
+ /** 默认排序(1.初始化时触发 2.排序方向为null时触发) */
81
+ defaultSort?: {
82
+ dataIndex: keyof T;
83
+ order: Order;
84
+ };
85
+ };
@@ -1,22 +1,41 @@
1
1
  import { interpolateRgb } from 'd3-interpolate';
2
- import { Ref, computed } from 'vue';
2
+ import { Ref, computed, ref } from 'vue';
3
3
  import { Highlight_Color, Highlight_Color_Change_Freq, Highlight_Duration } from './const';
4
+ import { UniqKey } from './types';
4
5
 
5
6
  type Params = {
6
7
  props: { theme: 'light' | 'dark'; virtual: boolean; dataSource: any[] };
7
8
  tableContainer: Ref<HTMLElement | undefined>;
8
- rowKeyGen: (p: any) => string;
9
9
  };
10
+
11
+ /** 高亮行保存的东西 */
12
+ type HighlightRowStore = {
13
+ bgc: string;
14
+ bgc_progress_ms: number;
15
+ bgc_progress: number;
16
+ };
17
+
18
+ /** 高亮行class */
19
+ const HIGHLIGHT_ROW_CLASS = 'highlight-row';
20
+ /** 高连单元格class */
21
+ const HIGHLIGHT_CELL_CLASS = 'highlight-cell';
22
+
10
23
  /**
11
24
  * 高亮单元格,行
12
25
  * row中新增_bgc_progress_ms 属性控制高亮状态,_bgc控制颜色
13
26
  */
14
- export function useHighlight({ props, tableContainer, rowKeyGen }: Params) {
15
- const highlightInter = computed(() => {
16
- return interpolateRgb(Highlight_Color[props.theme].from, Highlight_Color[props.theme].to);
17
- });
18
- /** 存放高亮行的对象*/
19
- const highlightDimRows = new Set<any>();
27
+ export function useHighlight({ props, tableContainer }: Params) {
28
+ /**
29
+ * 高亮行记录 key-rowKey, value-obj
30
+ */
31
+ const highlightRowStore = ref<Record<UniqKey, HighlightRowStore>>({});
32
+
33
+ const highlightFrom = Highlight_Color[props.theme].from;
34
+ const highlightTo = Highlight_Color[props.theme].to;
35
+ const highlightInter = computed(() => interpolateRgb(highlightFrom, highlightTo));
36
+
37
+ /** 存放高亮行的key*/
38
+ const highlightDimRowKeys = new Set<UniqKey>();
20
39
  /** 高亮后渐暗的行定时器 */
21
40
  const highlightDimRowsTimeout = new Map();
22
41
  /** 高亮后渐暗的单元格定时器 */
@@ -36,9 +55,8 @@ export function useHighlight({ props, tableContainer, rowKeyGen }: Params) {
36
55
  const recursion = () => {
37
56
  window.setTimeout(() => {
38
57
  const nowTs = Date.now();
39
- const needDeleteRows: any = [];
40
58
 
41
- highlightDimRows.forEach(row => {
59
+ highlightDimRowKeys.forEach(rowKeyValue => {
42
60
  // const rowKeyValue = rowKeyGen(row);
43
61
  // const rowEl = tableContainer.value?.querySelector<HTMLElement>(`[data-row-key="${rowKeyValue}"]`);
44
62
  // if (rowEl && row._bgc_progress === 0) {
@@ -47,21 +65,18 @@ export function useHighlight({ props, tableContainer, rowKeyGen }: Params) {
47
65
  // void rowEl.offsetHeight; // reflow
48
66
  // rowEl.classList.add('highlight-row-transition');
49
67
  // }
50
-
68
+ const highlightItem = highlightRowStore.value[rowKeyValue];
51
69
  /** 经过的时间 ÷ 高亮持续时间 计算出 颜色过渡进度 (0-1) */
52
- const progress = (nowTs - row._bgc_progress_ms) / Highlight_Duration;
53
- // row._bgc_progress = progress;
70
+ const progress = (nowTs - highlightItem.bgc_progress_ms) / Highlight_Duration;
54
71
  if (0 < progress && progress < 1) {
55
- row._bgc = highlightInter.value(progress);
72
+ highlightItem.bgc = highlightInter.value(progress);
56
73
  } else {
57
- row._bgc = ''; // 清空颜色
58
- needDeleteRows.push(row);
74
+ highlightItem.bgc = ''; // 清空颜色
75
+ highlightDimRowKeys.delete(rowKeyValue);
59
76
  }
60
77
  });
61
- needDeleteRows.forEach((row: any) => highlightDimRows.delete(row));
62
- // TODO: shallowRef 时,需要手动更新
63
78
 
64
- if (highlightDimRows.size > 0) {
79
+ if (highlightDimRowKeys.size > 0) {
65
80
  // 还有高亮的行,则下一次循环
66
81
  recursion();
67
82
  } else {
@@ -78,16 +93,16 @@ export function useHighlight({ props, tableContainer, rowKeyGen }: Params) {
78
93
  // TODO: 支持动态计算高亮颜色。不易实现。需记录每一个单元格的颜色情况。
79
94
  const cellEl = tableContainer.value?.querySelector<HTMLElement>(`[data-row-key="${rowKeyValue}"]>[data-index="${dataIndex}"]`);
80
95
  if (!cellEl) return;
81
- if (cellEl.classList.contains('highlight-cell')) {
82
- cellEl.classList.remove('highlight-cell');
96
+ if (cellEl.classList.contains(HIGHLIGHT_CELL_CLASS)) {
97
+ cellEl.classList.remove(HIGHLIGHT_CELL_CLASS);
83
98
  void cellEl.offsetHeight; // 通知浏览器重绘
84
99
  }
85
- cellEl.classList.add('highlight-cell');
100
+ cellEl.classList.add(HIGHLIGHT_CELL_CLASS);
86
101
  window.clearTimeout(highlightDimCellsTimeout.get(rowKeyValue));
87
102
  highlightDimCellsTimeout.set(
88
103
  rowKeyValue,
89
104
  window.setTimeout(() => {
90
- cellEl.classList.remove('highlight-cell');
105
+ cellEl.classList.remove(HIGHLIGHT_CELL_CLASS);
91
106
  highlightDimCellsTimeout.delete(rowKeyValue);
92
107
  }, Highlight_Duration),
93
108
  );
@@ -97,18 +112,19 @@ export function useHighlight({ props, tableContainer, rowKeyGen }: Params) {
97
112
  * 高亮一行
98
113
  * @param rowKeyValues
99
114
  */
100
- function setHighlightDimRow(rowKeyValues: Array<string | number>) {
115
+ function setHighlightDimRow(rowKeyValues: UniqKey[]) {
101
116
  if (!Array.isArray(rowKeyValues)) rowKeyValues = [rowKeyValues];
102
117
  if (props.virtual) {
103
118
  // --------虚拟滚动用js计算颜色渐变的高亮方案
104
119
  const nowTs = Date.now(); // 重置渐变进度
105
120
  for (let i = 0; i < rowKeyValues.length; i++) {
106
121
  const rowKeyValue = rowKeyValues[i];
107
- const row = props.dataSource.find((it: any) => rowKeyGen(it) === rowKeyValue);
108
- if (!row) continue;
109
- row._bgc_progress_ms = nowTs;
110
- // row._bgc_progress = 0;
111
- highlightDimRows.add(row);
122
+ highlightRowStore.value[rowKeyValue] = {
123
+ bgc: '',
124
+ bgc_progress: 0,
125
+ bgc_progress_ms: nowTs,
126
+ };
127
+ highlightDimRowKeys.add(rowKeyValue);
112
128
  }
113
129
  calcHighlightLoop();
114
130
  } else {
@@ -121,8 +137,8 @@ export function useHighlight({ props, tableContainer, rowKeyGen }: Params) {
121
137
  const rowKeyValue = rowKeyValues[i];
122
138
  const rowEl = tableContainer.value?.querySelector<HTMLTableRowElement>(`[data-row-key="${rowKeyValue}"]`);
123
139
  if (!rowEl) continue;
124
- if (rowEl.classList.contains('highlight-row')) {
125
- rowEl.classList.remove('highlight-row');
140
+ if (rowEl.classList.contains(HIGHLIGHT_ROW_CLASS)) {
141
+ rowEl.classList.remove(HIGHLIGHT_ROW_CLASS);
126
142
  needRepaint = true;
127
143
  }
128
144
  rowElTemp.push(rowEl);
@@ -131,7 +147,7 @@ export function useHighlight({ props, tableContainer, rowKeyGen }: Params) {
131
147
  highlightDimRowsTimeout.set(
132
148
  rowKeyValue,
133
149
  window.setTimeout(() => {
134
- rowEl.classList.remove('highlight-row');
150
+ rowEl.classList.remove(HIGHLIGHT_ROW_CLASS);
135
151
  highlightDimRowsTimeout.delete(rowKeyValue); // 回收内存
136
152
  }, Highlight_Duration),
137
153
  );
@@ -139,11 +155,12 @@ export function useHighlight({ props, tableContainer, rowKeyGen }: Params) {
139
155
  if (needRepaint) {
140
156
  void tableContainer.value?.offsetWidth; //强制浏览器重绘
141
157
  }
142
- rowElTemp.forEach(el => el.classList.add('highlight-row')); // 统一添加动画
158
+ rowElTemp.forEach(el => el.classList.add(HIGHLIGHT_ROW_CLASS)); // 统一添加动画
143
159
  }
144
160
  }
145
161
 
146
162
  return {
163
+ highlightRowStore,
147
164
  setHighlightDimRow,
148
165
  setHighlightDimCell,
149
166
  };
@@ -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,56 +63,95 @@ 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<T extends Record<string, any>>(sortOption: SortOption<T>, targetDataSource: T[], isNumber?: boolean) {
74
+ const emptyArr: T[] = [];
75
+ const valueArr: T[] = [];
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,使表格不排序。
69
97
  * 使用者在@sort-change事件中自行更改table props 'dataSource'完成排序。
70
98
  * TODO: key 唯一值,排序字段相同时,根据唯一值排序。
99
+ *
100
+ * sortConfig.defaultSort 会在order为null时生效
71
101
  * @param sortOption 列配置
72
102
  * @param order 排序方式
73
103
  * @param dataSource 排序的数组
74
104
  */
75
- export function tableSort(sortOption: SortOption, order: Order, dataSource: any[]): any[] {
105
+ export function tableSort<T extends Record<string, any>>(
106
+ sortOption: SortOption<T>,
107
+ order: Order,
108
+ dataSource: T[],
109
+ sortConfig: SortConfig<T> = {},
110
+ ): T[] {
76
111
  if (!dataSource?.length) return dataSource || [];
112
+ sortConfig = { emptyToBottom: false, ...sortConfig };
77
113
  let targetDataSource = [...dataSource];
114
+ let sortField = sortOption.sortField || sortOption.dataIndex;
115
+
116
+ if (!order && sortConfig.defaultSort) {
117
+ // 默认排序
118
+ order = sortConfig.defaultSort.order;
119
+ sortField = sortConfig.defaultSort.dataIndex;
120
+ }
121
+
78
122
  if (typeof sortOption.sorter === 'function') {
79
123
  const customSorterData = sortOption.sorter(targetDataSource, { order, column: sortOption });
80
124
  if (customSorterData) targetDataSource = customSorterData;
81
125
  } else if (order) {
82
- const sortField = sortOption.sortField || sortOption.dataIndex;
83
126
  let { sortType } = sortOption;
84
127
  if (!sortType) sortType = typeof dataSource[0][sortField] as 'number' | 'string';
85
128
 
129
+ const [valueArr, emptyArr] = separatedData(sortOption, targetDataSource, sortType === 'number');
130
+
86
131
  if (sortType === 'number') {
87
132
  // 按数字类型排序
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
133
  // 非数字当作最小值处理
100
134
  if (order === 'asc') {
101
- numArr.sort((a, b) => +a[sortField] - +b[sortField]);
102
- targetDataSource = [...nanArr, ...numArr];
135
+ valueArr.sort((a, b) => +a[sortField] - +b[sortField]);
136
+ targetDataSource = [...emptyArr, ...valueArr];
103
137
  } else {
104
- numArr.sort((a, b) => +b[sortField] - +a[sortField]);
105
- targetDataSource = [...numArr, ...nanArr];
138
+ valueArr.sort((a, b) => +b[sortField] - +a[sortField]);
139
+ targetDataSource = [...valueArr, ...emptyArr];
106
140
  }
107
- // targetDataSource = [...numArr, ...nanArr]; // 非数字不进入排序,一直排在最后
108
141
  } else {
109
142
  // 按string 排序
110
143
  if (order === 'asc') {
111
- targetDataSource.sort((a, b) => String(a[sortField]).localeCompare(b[sortField]));
144
+ valueArr.sort((a, b) => String(a[sortField]).localeCompare(b[sortField]));
145
+ targetDataSource = [...emptyArr, ...valueArr];
112
146
  } else {
113
- targetDataSource.sort((a, b) => String(a[sortField]).localeCompare(b[sortField]) * -1);
147
+ valueArr.sort((a, b) => String(a[sortField]).localeCompare(b[sortField]) * -1);
148
+ targetDataSource = [...valueArr, ...emptyArr];
114
149
  }
115
150
  }
151
+
152
+ if (sortConfig.emptyToBottom) {
153
+ targetDataSource = [...valueArr, ...emptyArr];
154
+ }
116
155
  }
117
156
  return targetDataSource;
118
157
  }