stk-table-vue 0.6.5 → 0.6.7

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 CHANGED
@@ -8,11 +8,9 @@ Vue3 简易虚拟滚动表格。用于实时数据展示,新数据行高亮渐
8
8
 
9
9
  Vue2.7支持引入源码(**ts**)使用。
10
10
 
11
- [Stk Table Vue 文档](https://ja-plus.github.io/stk-table-vue/)
11
+ [Stk Table Vue Doc](https://ja-plus.github.io/stk-table-vue/)
12
12
 
13
- ## License
14
- MIT
15
- repo:
13
+ repo(求 star🌟):
16
14
  - [Github](https://github.com/ja-plus/stk-table-vue)
17
15
  - [Gitee](https://gitee.com/japlus/stk-table-vue) 🇨🇳
18
16
 
@@ -96,521 +94,36 @@ const dataSource = [
96
94
  </script>
97
95
 
98
96
  <template>
99
- <StkTable ref='stkTableRef' row-key="id" :data-source="dataSource" :columns="columns" ></StkTable>
97
+ <StkTable ref='stkTableRef' row-key="id" :data-source="dataSource" :columns="columns"></StkTable>
100
98
  </template>
101
99
 
102
100
  ```
103
101
 
104
102
  ### Vue2.7 Usage
105
- vue2.7 支持引入源码使用。依赖`less`。
106
- ```html
107
- <script>
108
- import { StkTable } from 'stk-table-vue/src/StkTable/index'; // include less
109
- </script>
110
- ```
111
- Use `css`
112
- ```html
113
- <script>
114
- import StkTable from 'stk-table-vue/src/StkTable/StkTable.vue';
115
- import 'stk-table-vue/lib/style.css';
116
- </script>
117
- ```
118
- #### webpack TS
119
- ##### webpack.config.js
120
- ```js
121
- rules:[{
122
- test: /\.ts$/,
123
- loader:'swc-loader'
124
- }]
125
- ```
126
- ##### .swcrc
127
- ```json
128
- {
129
- "jsc":{
130
- "parser":{
131
- "syntax":"typescript",
132
- }
133
- }
134
- }
135
- ```
136
-
137
-
103
+ [在vue2中使用](https://ja-plus.github.io/stk-table-vue/main/start/vue2-usage.html)
138
104
 
139
105
  ## Notice
140
106
  注意,组件会改动 `props.columns` 中的对象。如果多个组件 `columns` 数组元素存在引用同一个 `StkTableColumn` 对象。则考虑赋值 `columns` 前进行深拷贝。
141
107
 
142
108
  ## API
143
- ### StkTable Component
144
- #### Props
145
- ```ts
146
- export type StkProps = {
147
- width?: string;
148
- /** 最小表格宽度 */
149
- minWidth?: string;
150
- /** 表格最大宽度*/
151
- maxWidth?: string;
152
- /** 斑马线条纹 */
153
- stripe?: boolean;
154
- /** 是否使用 table-layout:fixed */
155
- fixedMode?: boolean;
156
- /** 是否隐藏表头 */
157
- headless?: boolean;
158
- /** 主题,亮、暗 */
159
- theme?: 'light' | 'dark';
160
- /**
161
- * 行高
162
- * - `props.autoRowHeight` 为 `true` 时,将表示为期望行高,用于计算。不再影响实际行高。
163
- */
164
- rowHeight?: number;
165
- /**
166
- * 是否可变行高
167
- * - 设置为 `true` 时, `props.rowHeight` 将表示为期望行高,用于计算。不再影响实际行高。
168
- */
169
- autoRowHeight?: boolean | {
170
- /** 预估行高(优先级高于rowHeight) */
171
- expectedHeight?: number | ((row: DT, index: number) => number);
172
- };
173
- /** 是否高亮鼠标悬浮的行 */
174
- rowHover?: boolean;
175
- /** 是否高亮选中的行 */
176
- rowActive?: boolean;
177
- /** 当前行再次点击否可以取消 (rowActive=true)*/
178
- rowCurrentRevokable?: boolean;
179
- /** 表头行高。default = rowHeight */
180
- headerRowHeight?: number | null;
181
- /** 虚拟滚动 */
182
- virtual?: boolean;
183
- /** x轴虚拟滚动(必须设置列宽)*/
184
- virtualX?: boolean;
185
- /** 表格列配置 */
186
- columns?: StkTableColumn<any>[];
187
- /** 表格数据源 */
188
- dataSource?: any[];
189
- /** 行唯一键 (行唯一值不能为undefined)*/
190
- rowKey?: UniqKeyProp;
191
- /** 列唯一键。默认`dataIndex`*/
192
- colKey?: UniqKeyProp;
193
- /** 空值展示文字 */
194
- emptyCellText?: string | ((option: { row: DT; col: StkTableColumn<DT> }) => string);
195
- /** 暂无数据兜底高度是否撑满 */
196
- noDataFull?: boolean;
197
- /** 是否展示暂无数据 */
198
- showNoData?: boolean;
199
- /** 是否服务端排序,true则不排序数据 */
200
- sortRemote?: boolean;
201
- /** 表头是否溢出展示... */
202
- showHeaderOverflow?: boolean;
203
- /** 表体溢出是否展示... */
204
- showOverflow?: boolean;
205
- /** 是否增加行hover class */
206
- showTrHoverClass?: boolean;
207
- /** 是否高亮鼠标悬浮的单元格 */
208
- cellHover?: boolean;
209
- /** 是否高亮选中的单元格 */
210
- cellActive?: boolean;
211
- /** 单元格再次点击否可以取消选中 (cellActive=true)*/
212
- selectedCellRevokable?: boolean;
213
- /** 表头是否可拖动。支持回调函数。 */
214
- headerDrag?:
215
- | boolean
216
- | {
217
- /**
218
- * 列交换模式
219
- * - none - 不做任何事
220
- * - insert - 插入(默认值)
221
- * - swap - 交换
222
- */
223
- mode?: 'none' | 'insert' | 'swap';
224
- /** 禁用拖动的列 */
225
- disabled?: (col: StkTableColumn<DT>) => boolean;
226
- };
227
- /**
228
- * 给行附加className<br>
229
- * FIXME: 是否需要优化,因为不传此prop会使表格行一直执行空函数,是否有影响
230
- */
231
- rowClassName?: (row: any, i: number) => string;
232
- /**
233
- * 列宽是否可拖动(需要设置v-model:columns)<br>
234
- * **不要设置**列minWidth,**必须**设置width<br>
235
- * 列宽拖动时,每一列都必须要有width,且minWidth/maxWidth不生效。table width会变为"fit-content"。
236
- * - 会自动更新props.columns中的with属性
237
- */
238
- colResizable?: boolean | ColResizableConfig;
239
- /** 可拖动至最小的列宽 */
240
- colMinWidth?: number;
241
- /**
242
- * 单元格分割线。
243
- * 默认横竖都有
244
- * "h" - 仅展示横线
245
- * "v" - 仅展示竖线
246
- * "body-v" - 仅表体展示竖线
247
- */
248
- bordered?: boolean | 'h' | 'v' | 'body-v';
249
- /**
250
- * 自动重新计算虚拟滚动高度宽度。默认true
251
- * [非响应式]
252
- * 传入方法表示resize后的回调
253
- */
254
- autoResize?: boolean | (() => void);
255
- /** 是否展示固定列阴影。为节省性能,默认false。 */
256
- fixedColShadow?: boolean;
257
- /** 优化vue2 滚动 */
258
- optimizeVue2Scroll?: boolean;
259
- /** 排序配置 */
260
- sortConfig?: {
261
- /** 空值是否排最下面 */
262
- emptyToBottom: boolean,
263
- /** 默认排序(1.初始化时触发 2.排序方向为null时触发) */
264
- defaultSort?: {
265
- dataIndex: keyof T;
266
- order: Order;
267
- };
268
- /**
269
- * string排序是否使用 String.prototype.localCompare
270
- * 默认true (历史设计问题,为了兼容,默认true)
271
- */
272
- stringLocaleCompare?: boolean;
273
- },
274
- /** 隐藏头部鼠标悬浮title。可传入dataIndex数组 */
275
- hideHeaderTitle?: boolean | string[];
276
- /** 高亮配置 */
277
- highlightConfig?: {
278
- /** 高亮持续时间(s) */
279
- duration?: number;
280
- /** 高亮帧率*/
281
- fps?: number;
282
- };
283
- /** 序号列配置 */
284
- seqConfig?: {
285
- /** 序号列起始下标 用于适配分页 */
286
- startIndex?: number;
287
- };
288
- /** 展开行配置 */
289
- expandConfig?: {
290
- height?: number;
291
- };
292
- /** 行拖动配置 */
293
- dragRowConfig?: {
294
- mode?: 'none' | 'insert' | 'swap';
295
- };
296
- /**
297
- * 固定头,固定列实现方式。
298
- * [非响应式]
299
- * relative:固定列只能放在props.columns的两侧。
300
- * - 如果列宽会变动则谨慎使用。
301
- * - 多级表头固定列慎用
302
- *
303
- * 低版本浏览器只能为'relative',
304
- */
305
- cellFixedMode?: 'sticky' | 'relative';
306
- /**
307
- * 是否平滑滚动
308
- * - default: chrome < 85 ? true : false
309
- * - false: 使用 wheel 事件滚动。为了防止滚动过快导致白屏。
310
- * - true: 不使用 wheel 事件滚动。滚轮滚动时更加平滑。滚动过快时会白屏。
311
- */
312
- smoothScroll?: boolean;
313
- };
314
- ```
315
-
316
- #### Emits
317
- ```js
318
- {
319
- /**
320
- * 排序变更触发。defaultSort.dataIndex 找不到时,col 将返回null。
321
- * ```(col: StkTableColumn<DT> | null, order: Order, data: DT[], sortConfig: SortConfig<DT>)```
322
- */
323
- (e: 'sort-change', col: StkTableColumn<DT> | null, order: Order, data: DT[], sortConfig: SortConfig): void;
324
- /**
325
- * 一行点击事件
326
- * ```(ev: MouseEvent, row: DT)```
327
- */
328
- (e: 'row-click', ev: MouseEvent, row: DT): void;
329
- /**
330
- * 选中一行触发。ev返回null表示不是点击事件触发的
331
- * ```(ev: MouseEvent | null, row: DT | undefined,, data: { select: boolean })```
332
- */
333
- (e: 'current-change', ev: MouseEvent | null, row: DT | undefined,, data: { select: boolean }): void;
334
- /**
335
- * 选中单元格触发。ev返回null表示不是点击事件触发的
336
- * ```(ev: MouseEvent | null, data: { select: boolean; row: DT | undefined; col: StkTableColumn<DT> | null })```
337
- */
338
- (e: 'cell-selected', ev: MouseEvent | null, data: { select: boolean; row: DT | undefined; col: StkTableColumn<DT> | null }): void;
339
- /**
340
- * 行双击事件
341
- * ```(ev: MouseEvent, row: DT)```
342
- */
343
- (e: 'row-dblclick', ev: MouseEvent, row: DT): void;
344
- /**
345
- * 表头右键事件
346
- * ```(ev: MouseEvent)```
347
- */
348
- (e: 'header-row-menu', ev: MouseEvent): void;
349
- /**
350
- * 表体行右键点击事件
351
- * ```(ev: MouseEvent, row: DT)```
352
- */
353
- (e: 'row-menu', ev: MouseEvent, row: DT): void;
354
- /**
355
- * 单元格点击事件
356
- * ```(ev: MouseEvent, row: DT, col: StkTableColumn<DT>)```
357
- */
358
- (e: 'cell-click', ev: MouseEvent, row: DT, col: StkTableColumn<DT>): void;
359
- /**
360
- * 单元格鼠标进入事件
361
- * ```(ev: MouseEvent, row: DT, col: StkTableColumn<DT>)```
362
- */
363
- (e: 'cell-mouseenter', ev: MouseEvent, row: DT, col: StkTableColumn<DT>): void;
364
- /**
365
- * 单元格鼠标移出事件
366
- * ```(ev: MouseEvent, row: DT, col: StkTableColumn<DT>)```
367
- */
368
- (e: 'cell-mouseleave', ev: MouseEvent, row: DT, col: StkTableColumn<DT>): void;
369
- /**
370
- * 单元格悬浮事件
371
- * ```(ev: MouseEvent, row: DT, col: StkTableColumn<DT>)```
372
- */
373
- (e: 'cell-mouseover', ev: MouseEvent, row: DT, col: StkTableColumn<DT>): void;
374
- /**
375
- * 表头单元格点击事件
376
- * ```(ev: MouseEvent, col: StkTableColumn<DT>)```
377
- */
378
- (e: 'header-cell-click', ev: MouseEvent, col: StkTableColumn<DT>): void;
379
- /**
380
- * 表格滚动事件
381
- * ```(ev: Event, data: { startIndex: number; endIndex: number })```
382
- */
383
- (e: 'scroll', ev: Event, data: { startIndex: number; endIndex: number }): void;
384
- /**
385
- * 表格横向滚动事件
386
- * ```(ev: Event)```
387
- */
388
- (e: 'scroll-x', ev: Event): void;
389
- /**
390
- * 表头列拖动事件
391
- * ```(dragStartKey: string, targetColKey: string)```
392
- */
393
- (e: 'col-order-change', dragStartKey: string, targetColKey: string): void;
394
- /**
395
- * 表头列拖动开始
396
- * ```(dragStartKey: string)```
397
- */
398
- (e: 'th-drag-start', dragStartKey: string): void;
399
- /**
400
- * 表头列拖动drop
401
- * ```(targetColKey: string)```
402
- */
403
- (e: 'th-drop', targetColKey: string): void;
404
- /**
405
- * 行拖动事件
406
- * ```(dragStartKey: string, targetRowKey: string)```
407
- */
408
- (e: 'row-order-change', dragStartKey: string, targetRowKey: string): void;
409
- /**
410
- * 列宽变动时触发
411
- */
412
- (e: 'col-resize', cols: StkTableColumn<DT>): void;
413
- /**
414
- * 展开行触发
415
- * ```( data: { expanded: boolean; row: DT; col: StkTableColumn<DT> })```
416
- */
417
- (e: 'toggle-row-expand', data: { expanded: boolean; row: DT; col: StkTableColumn<DT> | null }): void;
418
- /**
419
- * v-model:columns col resize 时更新宽度
420
- */
421
- (e: 'update:columns', cols: StkTableColumn<DT>[]): void;
422
- }
423
- ```
109
+ ### Props
110
+ [Props 表格配置](https://ja-plus.github.io/stk-table-vue/main/api/table-props.html)
424
111
 
425
- #### Slots
112
+ ### Emits
113
+ [Emits 事件](https://ja-plus.github.io/stk-table-vue/main/api/emits.html)
426
114
 
427
- | slots | props | describe |
428
- | ---- | ---- | ---- |
429
- | `tableHeader` | `{col}` | table header slot |
430
- | `empty` | -- | no data status |
431
- | `expand` | `{col, row}` | expand row |
115
+ ### Slots
116
+ [Slots 插槽](https://ja-plus.github.io/stk-table-vue/main/api/slots.html)
432
117
 
433
-
434
- #### Expose
435
- ```js
436
- defineExpose({
437
- /** 初始化横向纵向虚拟滚动 */
438
- initVirtualScroll,
439
- /** 初始化横向虚拟滚动 */
440
- initVirtualScrollX,
441
- /** 初始化纵向虚拟滚动 */
442
- initVirtualScrollY,
443
- /** 设置当前选中行 */
444
- setCurrentRow,
445
- /** 设置当前选中单元格 (props.cellActive=true)*/
446
- setSelectedCell,
447
- /** 设置高亮渐暗单元格 */
448
- setHighlightDimCell,
449
- /** 设置高亮渐暗行 */
450
- setHighlightDimRow,
451
- /** 表格排序列dataIndex */
452
- sortCol,
453
- /** 获取当前排序状态 */
454
- getSortColumns,
455
- /** 设置排序 */
456
- setSorter,
457
- /** 重置排序 */
458
- resetSorter,
459
- /** 滚动至 */
460
- scrollTo,
461
- /** 获取表格数据 */
462
- getTableData,
463
- /** 设置展开行*/
464
- setRowExpand,
465
- /** 设置指定行的 auto-row-height 保存的高度,如果行高度有变化,则可以调用此方法清除或变更行高 */
466
- setAutoHeight,
467
- /** 清除所有 auto-row-height 保存的高度 */
468
- clearAllAutoHeight,
469
- });
470
- ```
118
+ ### Expose
119
+ [Expose 实例方法](https://ja-plus.github.io/stk-table-vue/main/api/expose.html)
471
120
 
472
121
  ### StkTableColumn 列配置
473
- ``` ts
474
- type Sorter<T> = boolean | ((data: T[], option: { order: Order; column: any }) => T[]);
475
- export type StkTableColumn<T extends Record<string, any>> = {
476
- /**
477
- * 用于区分相同dataIndex 的列。
478
- * 需要自行配置colKey="(col: StkTableColumn<any>) => col.key ?? col.dataIndex"
479
- */
480
- key?: any;
481
- /**
482
- * 列类型
483
- * - seq 序号列
484
- * - expand 展开列
485
- * - dragRow 拖拽列(使用sktTableRef.getTableData 获取改变后的顺序)
486
- */
487
- type?: 'seq' | 'expand' | 'dragRow';
488
- /** 取值id */
489
- dataIndex: keyof T & string;
490
- /** 表头文字 */
491
- title?: string;
492
- /** 列内容对齐方式 */
493
- align?: 'right' | 'left' | 'center';
494
- /** 表头内容对齐方式 */
495
- headerAlign?: 'right' | 'left' | 'center';
496
- /** 筛选 */
497
- sorter?: Sorter<T>;
498
- /** 列宽。横向虚拟滚动时必须设置。 */
499
- width?: string | number;
500
- /** 最小列宽。非x虚拟滚动生效。 */
501
- minWidth?: string | number;
502
- /** 最大列宽。非x虚拟滚动生效。 */
503
- maxWidth?: string | number;
504
- /**th class */
505
- headerClassName?: string;
506
- /** td class */
507
- className?: string;
508
- /** 排序字段。default: dataIndex */
509
- sortField?: keyof T;
510
- /** 排序方式。按数字/字符串 */
511
- sortType?: 'number' | 'string';
512
- /** 固定列 */
513
- fixed?: 'left' | 'right' | null;
514
- /** private */ rowSpan?: number;
515
- /** private */ colSpan?: number;
516
- /**
517
- * 自定义 td 渲染内容。
518
- *
519
- * 组件prop入参:
520
- * @param props.row 一行的记录。
521
- * @param props.col 列配置
522
- * @param props.cellValue row[col.dataIndex] 的值
523
- * @param props.rowIndex 行索引
524
- * @param props.colIndex 列索引
525
- */
526
- customCell?: Component<CustomCellProps<T>> | string;
527
- /**
528
- * 自定义 th 渲染内容
529
- *
530
- * 组件prop入参:
531
- * @param props.col 列配置
532
- * @param props.rowIndex 行索引
533
- * @param props.colIndex 列索引
534
- */
535
- customHeaderCell?: Component<CustomHeaderCellProps<T>> | string;
536
- /** 二级表头 */
537
- children?: StkTableColumn<T>[];
538
- /** private 父节点引用 */
539
- __PARENT__?: StkTableColumn<T> | null;
540
- /** private 保存计算的宽度。横向虚拟滚动用。 */
541
- __WIDTH__?: number;
542
- };
543
- ```
544
-
545
-
546
- ### StkTableColumn.SortConfig
547
- ```ts
548
- /** 排序配置 */
549
- export type SortConfig<T extends Record<string, any>> = {
550
- /** 空值始终排在列表末尾 */
551
- emptyToBottom?: boolean;
552
- /**
553
- * 默认排序(1.初始化时触发 2.排序方向为null时触发)
554
- * 类似onMounted时,调用setSorter点了下表头。
555
- */
556
- defaultSort?: {
557
- dataIndex: keyof T;
558
- order: Order;
559
- /** 是否禁止触发sort-change事件。默认false,表示触发事件。 */
560
- silent?: boolean;
561
- };
562
- /**
563
- * string排序是否使用 String.prototype.localCompare
564
- * 默认true ($*$应该false)
565
- */
566
- stringLocaleCompare?: boolean;
567
- };
568
- ```
122
+ [StkTableColumn 列配置](https://ja-plus.github.io/stk-table-vue/main/api/stk-table-column.html)
569
123
 
570
124
  ### setHighlightDimCell & setHighlightDimRow
571
- #### setHighlightDimCell
572
- ```ts
573
- setHighlightDimCell(
574
- rowKeyValues: UniqKey[],
575
- option: {
576
- method?: 'css' | 'animation' | 'js';
577
- /** @deprecated use method */
578
- useCss?: boolean;
579
- className?: string;
580
- keyframe?: Parameters<Animatable['animate']>['0'];
581
- duration?: number;
582
- } = {},
583
- )
584
- ```
585
- #### setHighlightDimRow
586
- ```ts
587
- setHighlightDimRow(
588
- rowKeyValues: UniqKey[],
589
- option: {
590
- method?: 'css' | 'animation' | 'js';
591
- /** @deprecated use method */
592
- useCss?: boolean;
593
- className?: string;
594
- keyframe?: Parameters<Animatable['animate']>['0'];
595
- duration?: number;
596
- }
597
- )
598
- ```
599
- #### option
600
- | key |value| default |desc |
601
- | ---- | ---- | ---- | ---- |
602
- | method | `css` `animation` `js` | `animation` | 设置高亮方式。 |
603
- | ~~useCss~~ `deprecated` | `boolean`| false | ~~是否使用css~~ |
604
- | className | `string` | `highlight-row`/`highlight-cell` | 自定义 css 动画。method == 'css' 生效 |
605
- | keyframe | `Parameters<Animatable['animate']>['0']` | ... | 自定义高亮动画。method == 'animation' 生效。 |
606
- | duration | `number` | 2000 | 设置高亮动画持续时间ms。 method='css'状态下,用于移除class,如果传入了className则需要与自定义的动画时间一致。|
125
+ [高亮使用文档](https://ja-plus.github.io/stk-table-vue/main/api/expose.html#sethighlightdimcell)
607
126
 
608
- ##### option.method
609
- | `option.method`| desc |
610
- | ---- | ---- |
611
- | animation | animation api 实现高亮。(default) |
612
- | css | css @keyframes 实现高亮。 |
613
- | js | js 循环计算颜色实现高亮。 |
614
127
 
615
128
  ### Example
616
129
  ```vue
@@ -687,32 +200,12 @@ export type SortConfig<T extends Record<string, any>> = {
687
200
  ### Filter过滤器
688
201
  * 暂不支持。用户可以自行通过 `customHeaderCell` 实现功能。
689
202
 
690
- ## Performance optimization
691
- ### highlight
692
- * 配置 `props.highlightConfig.fps` 指定高亮帧率。降低帧率有利于性能。
693
- ### relative fixed
694
- * 配置 `props.cellFixedMode` 为 `relative` 时,将使用相对定位实现固定列与固定表头,相较于`sticky`的实现,渲染合成层更少。
695
- * 问题:若开启了纵向虚拟滚动,不开启横向虚拟滚动,且不设置某些列宽时。如果纵向滚动导致某些列宽变化,则会导致右侧固定列计算错误。
696
- ### tr 分层
697
- * 通过css选择器将 stk-table tbody tr 配置 `transform:translateZ(0)` 对每行 tr 进行分层。对性能有帮助。
698
- - 提升合成层可能导致黑底红字字体颜色发生变化。
699
- - 以下情况尝试开启此功能。
700
- - 在 `customCell` 较多且复杂时。
701
- - 大量 highlight 动画时。
702
- ### props.autoResize
703
- * 手动设置为 `props.autoResize=false`。可取消监听的性能消耗。适用于宽度高度不变的表格。
704
-
705
- ### props.smoothScroll
706
- * 高版本浏览器滚动默认有惯性。会频繁触发 `onscroll` 回调。因此 chrome > 85 默认关闭,使用 `onwheel` 代理滚动,且可防止滚动白屏。
707
-
708
203
  ## Tips
709
204
  ### props.fixedMode
710
205
  * **低版本浏览器** 需要设置 `props.width`(default: width=fit-content不生效)。否则列宽不设宽度会变为0。
711
206
 
712
-
713
207
  ## Other
714
208
  * `$*$` 兼容注释
715
209
 
716
-
717
210
  ### Planed removal APi
718
211
  * `setHighlightDimRow` 中的 `method="js"`。观察animation Api 是否足够满足使用场景。若足够满足计划在后期移除,并且可以移除 `d3-interpolate` 依赖。
@@ -26,6 +26,7 @@ declare function setSelectedCell(row?: DT, col?: StkTableColumn<DT>, option?: {
26
26
  * @param option.sort 是否触发排序-默认true
27
27
  * @param option.silent 是否禁止触发回调-默认true
28
28
  * @param option.force 是否触发排序-默认true
29
+ * @return 表格数据
29
30
  */
30
31
  declare function setSorter(colKey: string, order: Order, option?: {
31
32
  sortOption?: SortOption<DT>;
@@ -42,7 +43,10 @@ declare function resetSorter(): void;
42
43
  declare function scrollTo(top?: number | null, left?: number | null): void;
43
44
  /** get current table data */
44
45
  declare function getTableData(): any[];
45
- /** get current sort info */
46
+ /**
47
+ * get current sort info
48
+ * @return {{key:string,order:Order}[]}
49
+ */
46
50
  declare function getSortColumns(): {
47
51
  key: string | number | symbol | undefined;
48
52
  order: "desc" | "asc";
@@ -492,6 +496,7 @@ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<{
492
496
  col: any;
493
497
  }): any;
494
498
  empty?(_: {}): any;
499
+ customBottom?(_: {}): any;
495
500
  }>;
496
501
  export default _default;
497
502
  type __VLS_WithTemplateSlots<T, S> = T & {
@@ -1,3 +1,3 @@
1
1
  export { default as StkTable } from './StkTable.vue';
2
- export { tableSort, insertToOrderedArray, strCompare } from './utils';
2
+ export { tableSort, insertToOrderedArray, strCompare, binarySearch } from './utils';
3
3
  export type { StkTableColumn } from './types/index';
@@ -14,6 +14,12 @@ export declare function isEmptyValue(val: any, isNumber?: boolean): boolean;
14
14
  * @return targetArray 的浅拷贝
15
15
  */
16
16
  export declare function insertToOrderedArray<T extends object>(sortState: SortState<T>, newItem: T, targetArray: T[], sortConfig?: SortConfig<T>): T[];
17
+ /**
18
+ * 二分查找
19
+ * @param searchArray 查找数组
20
+ * @param compareCallback 比较函数,返回 -1|0|1
21
+ */
22
+ export declare function binarySearch(searchArray: any[], compareCallback: (midIndex: number) => number): number;
17
23
  /**
18
24
  * 字符串比较
19
25
  * @param a
@@ -21,7 +27,7 @@ export declare function insertToOrderedArray<T extends object>(sortState: SortSt
21
27
  * @param type 类型
22
28
  * @param isNumber 是否是数字类型
23
29
  * @param localeCompare 是否 使用Array.prototyshpe.localeCompare
24
- * @return {-1|0|1}
30
+ * @return {number} <0: a < b, 0: a = b, >0: a > b
25
31
  */
26
32
  export declare function strCompare(a: string, b: string, isNumber: boolean, localeCompare?: boolean): number;
27
33
  /**
@@ -59,7 +59,6 @@ function insertToOrderedArray(sortState, newItem, targetArray, sortConfig = {})
59
59
  sortConfig = { emptyToBottom: false, ...sortConfig };
60
60
  let { sortType } = sortState;
61
61
  if (!sortType) sortType = typeof newItem[dataIndex];
62
- const isNumber = sortType === "number";
63
62
  const data = [...targetArray];
64
63
  if (!order || !data.length) {
65
64
  data.unshift(newItem);
@@ -68,26 +67,32 @@ function insertToOrderedArray(sortState, newItem, targetArray, sortConfig = {})
68
67
  if (sortConfig.emptyToBottom && isEmptyValue(newItem)) {
69
68
  data.push(newItem);
70
69
  }
71
- let sIndex = 0;
72
- let eIndex = data.length - 1;
70
+ const isNumber = sortType === "number";
73
71
  const targetVal = newItem[dataIndex];
74
- while (sIndex <= eIndex) {
75
- const midIndex = Math.floor((sIndex + eIndex) / 2);
72
+ const sIndex = binarySearch(data, (midIndex) => {
76
73
  const midVal = data[midIndex][dataIndex];
77
74
  const compareRes = strCompare(midVal, targetVal, isNumber, sortConfig.stringLocaleCompare);
75
+ return order === "asc" ? compareRes : -compareRes;
76
+ });
77
+ data.splice(sIndex, 0, newItem);
78
+ return data;
79
+ }
80
+ function binarySearch(searchArray, compareCallback) {
81
+ let sIndex = 0;
82
+ let eIndex = searchArray.length - 1;
83
+ while (sIndex <= eIndex) {
84
+ const midIndex = Math.floor((sIndex + eIndex) / 2);
85
+ const compareRes = compareCallback(midIndex);
78
86
  if (compareRes === 0) {
79
87
  sIndex = midIndex;
80
88
  break;
81
- } else if (compareRes === -1) {
82
- if (order === "asc") sIndex = midIndex + 1;
83
- else eIndex = midIndex - 1;
89
+ } else if (compareRes < 0) {
90
+ sIndex = midIndex + 1;
84
91
  } else {
85
- if (order === "asc") eIndex = midIndex - 1;
86
- else sIndex = midIndex + 1;
92
+ eIndex = midIndex - 1;
87
93
  }
88
94
  }
89
- data.splice(sIndex, 0, newItem);
90
- return data;
95
+ return sIndex;
91
96
  }
92
97
  function strCompare(a, b, isNumber, localeCompare = false) {
93
98
  let _a = a;
@@ -2343,13 +2348,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2343
2348
  renderSlot(_ctx.$slots, "empty", {}, () => [
2344
2349
  _cache[7] || (_cache[7] = createTextVNode("暂无数据"))
2345
2350
  ])
2346
- ], 2)) : createCommentVNode("", true)
2351
+ ], 2)) : createCommentVNode("", true),
2352
+ renderSlot(_ctx.$slots, "customBottom")
2347
2353
  ], 38);
2348
2354
  };
2349
2355
  }
2350
2356
  });
2351
2357
  export {
2352
2358
  _sfc_main as StkTable,
2359
+ binarySearch,
2353
2360
  insertToOrderedArray,
2354
2361
  strCompare,
2355
2362
  tableSort
package/lib/style.css CHANGED
@@ -6,6 +6,7 @@
6
6
  .stk-table{
7
7
  --row-height:28px;
8
8
  --header-row-height:var(--row-height);
9
+ --cell-padding-y:0;
9
10
  --cell-padding-x:8px;
10
11
  --resize-handle-width:4px;
11
12
  --border-color:#e8e8f4;
@@ -103,13 +104,13 @@
103
104
  .stk-table.stripe.vt-on .stk-tbody-main tr:nth-child(odd){
104
105
  background-color:var(--stripe-bgc);
105
106
  }
106
- .stk-table.stripe.row-hover .stk-table-main .stk-tbody-main tr:hover{
107
+ .stk-table.stripe.row-hover .stk-tbody-main tr:hover{
107
108
  background-color:var(--tr-hover-bgc);
108
109
  }
109
- .stk-table.stripe.row-active .stk-table-main .stk-tbody-main tr.active{
110
+ .stk-table.stripe.row-active .stk-tbody-main tr.active{
110
111
  background-color:var(--tr-active-bgc);
111
112
  }
112
- .stk-table.row-hover .stk-table-main .stk-tbody-main tr:hover{
113
+ .stk-table.row-hover .stk-tbody-main tr:hover{
113
114
  background-color:var(--tr-hover-bgc);
114
115
  }
115
116
  .stk-table.row-active .stk-tbody-main tr.active{
@@ -177,7 +178,7 @@
177
178
  .stk-table td{
178
179
  font-size:14px;
179
180
  box-sizing:border-box;
180
- padding:0 var(--cell-padding-x);
181
+ padding:var(--cell-padding-y) var(--cell-padding-x);
181
182
  }
182
183
  .stk-table th{
183
184
  color:var(--th-color);
@@ -260,7 +261,7 @@
260
261
  .stk-table .expand-cell{
261
262
  cursor:pointer;
262
263
  }
263
- .stk-table .expand-cell .table-cell-wrapper.expanded-cell-wrapper::before{
264
+ .stk-table .expand-cell .expanded-cell-wrapper::before{
264
265
  content:'';
265
266
  display:inline-block;
266
267
  margin:0 2px;
@@ -271,7 +272,7 @@
271
272
  border-bottom:4px solid transparent;
272
273
  transition:transform 0.2s ease;
273
274
  }
274
- .stk-table .expand-cell .table-cell-wrapper.expanded-cell-wrapper > span{
275
+ .stk-table .expand-cell .expanded-cell-wrapper > span{
275
276
  margin-left:var(--cell-padding-x);
276
277
  }
277
278
  .stk-table .expand-cell.expanded .table-cell-wrapper::before{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stk-table-vue",
3
- "version": "0.6.5",
3
+ "version": "0.6.7",
4
4
  "description": "Simple realtime virtual table for vue3 and vue2.7",
5
5
  "main": "./lib/stk-table-vue.js",
6
6
  "types": "./lib/src/StkTable/index.d.ts",
@@ -227,6 +227,7 @@
227
227
  <div v-if="(!dataSourceCopy || !dataSourceCopy.length) && showNoData" class="stk-table-no-data" :class="{ 'no-data-full': noDataFull }">
228
228
  <slot name="empty">暂无数据</slot>
229
229
  </div>
230
+ <slot name="customBottom"></slot>
230
231
  </div>
231
232
  </template>
232
233
 
@@ -1288,6 +1289,7 @@ function setSelectedCell(row?: DT, col?: StkTableColumn<DT>, option = { silent:
1288
1289
  * @param option.sort 是否触发排序-默认true
1289
1290
  * @param option.silent 是否禁止触发回调-默认true
1290
1291
  * @param option.force 是否触发排序-默认true
1292
+ * @return 表格数据
1291
1293
  */
1292
1294
  function setSorter(colKey: string, order: Order, option: { sortOption?: SortOption<DT>; force?: boolean; silent?: boolean; sort?: boolean } = {}) {
1293
1295
  const newOption = { silent: true, sortOption: null, sort: true, ...option };
@@ -1325,7 +1327,10 @@ function getTableData() {
1325
1327
  return toRaw(dataSourceCopy.value);
1326
1328
  }
1327
1329
 
1328
- /** get current sort info */
1330
+ /**
1331
+ * get current sort info
1332
+ * @return {{key:string,order:Order}[]}
1333
+ */
1329
1334
  function getSortColumns() {
1330
1335
  const sortOrder = sortSwitchOrder[sortOrderIndex.value];
1331
1336
  if (!sortOrder) return [];
@@ -1,4 +1,4 @@
1
1
  export { default as StkTable } from './StkTable.vue';
2
- export { tableSort, insertToOrderedArray, strCompare } from './utils';
2
+ export { tableSort, insertToOrderedArray, strCompare, binarySearch } from './utils';
3
3
  export type { StkTableColumn } from './types/index';
4
4
  import './style.less';
@@ -9,6 +9,7 @@
9
9
  /* contain: strict;*/
10
10
  --row-height: 28px;
11
11
  --header-row-height: var(--row-height);
12
+ --cell-padding-y: 0;
12
13
  --cell-padding-x: 8px;
13
14
  --resize-handle-width: 4px;
14
15
  --border-color: #e8e8f4;
@@ -157,18 +158,18 @@
157
158
  background-color: var(--stripe-bgc);
158
159
  }
159
160
 
160
- &.row-hover .stk-table-main .stk-tbody-main tr:hover {
161
+ &.row-hover .stk-tbody-main tr:hover {
161
162
  background-color: var(--tr-hover-bgc);
162
163
  }
163
164
 
164
- &.row-active .stk-table-main .stk-tbody-main tr.active {
165
+ &.row-active .stk-tbody-main tr.active {
165
166
  background-color: var(--tr-active-bgc);
166
167
  }
167
168
  }
168
169
 
169
170
 
170
171
  /** more weight for custom row background*/
171
- &.row-hover .stk-table-main .stk-tbody-main tr:hover {
172
+ &.row-hover .stk-tbody-main tr:hover {
172
173
  background-color: var(--tr-hover-bgc);
173
174
  }
174
175
 
@@ -271,7 +272,7 @@
271
272
  td {
272
273
  font-size: 14px;
273
274
  box-sizing: border-box;
274
- padding: 0 var(--cell-padding-x);
275
+ padding: var(--cell-padding-y) var(--cell-padding-x);
275
276
  }
276
277
 
277
278
  th {
@@ -386,8 +387,7 @@
386
387
  .expand-cell {
387
388
  cursor: pointer;
388
389
 
389
- .table-cell-wrapper {
390
- &.expanded-cell-wrapper {
390
+ .expanded-cell-wrapper {
391
391
  &::before {
392
392
  content: '';
393
393
  display: inline-block;
@@ -404,7 +404,6 @@
404
404
  margin-left: var(--cell-padding-x)
405
405
  }
406
406
  }
407
- }
408
407
 
409
408
  &.expanded {
410
409
  .table-cell-wrapper::before {
@@ -26,7 +26,6 @@ export function insertToOrderedArray<T extends object>(sortState: SortState<T>,
26
26
  sortConfig = { emptyToBottom: false, ...sortConfig };
27
27
  let { sortType } = sortState;
28
28
  if (!sortType) sortType = typeof newItem[dataIndex] as 'number' | 'string';
29
- const isNumber = sortType === 'number';
30
29
  const data = [...targetArray];
31
30
 
32
31
  if (!order || !data.length) {
@@ -40,31 +39,43 @@ export function insertToOrderedArray<T extends object>(sortState: SortState<T>,
40
39
  data.push(newItem);
41
40
  }
42
41
 
42
+ const isNumber = sortType === 'number';
43
+
43
44
  // 二分插入
44
- let sIndex = 0;
45
- let eIndex = data.length - 1;
46
45
  const targetVal: any = newItem[dataIndex];
47
- while (sIndex <= eIndex) {
48
- // console.log(sIndex, eIndex);
49
- const midIndex = Math.floor((sIndex + eIndex) / 2);
46
+ const sIndex = binarySearch(data, midIndex => {
50
47
  const midVal: any = data[midIndex][dataIndex];
51
48
  const compareRes = strCompare(midVal, targetVal, isNumber, sortConfig.stringLocaleCompare);
49
+ return order === 'asc' ? compareRes : -compareRes;
50
+ });
51
+ data.splice(sIndex, 0, newItem);
52
+ return data;
53
+ }
54
+
55
+ /**
56
+ * 二分查找
57
+ * @param searchArray 查找数组
58
+ * @param compareCallback 比较函数,返回 -1|0|1
59
+ */
60
+ export function binarySearch(searchArray: any[], compareCallback: (midIndex: number) => number) {
61
+ let sIndex = 0;
62
+ let eIndex = searchArray.length - 1;
63
+ while (sIndex <= eIndex) {
64
+ const midIndex = Math.floor((sIndex + eIndex) / 2);
65
+ const compareRes = compareCallback(midIndex);
52
66
  if (compareRes === 0) {
53
67
  //midVal == targetVal
54
68
  sIndex = midIndex;
55
69
  break;
56
- } else if (compareRes === -1) {
70
+ } else if (compareRes < 0) {
57
71
  // midVal < targetVal
58
- if (order === 'asc') sIndex = midIndex + 1;
59
- else eIndex = midIndex - 1;
72
+ sIndex = midIndex + 1;
60
73
  } else {
61
74
  //midVal > targetVal
62
- if (order === 'asc') eIndex = midIndex - 1;
63
- else sIndex = midIndex + 1;
75
+ eIndex = midIndex - 1;
64
76
  }
65
77
  }
66
- data.splice(sIndex, 0, newItem);
67
- return data;
78
+ return sIndex;
68
79
  }
69
80
  /**
70
81
  * 字符串比较
@@ -73,7 +84,7 @@ export function insertToOrderedArray<T extends object>(sortState: SortState<T>,
73
84
  * @param type 类型
74
85
  * @param isNumber 是否是数字类型
75
86
  * @param localeCompare 是否 使用Array.prototyshpe.localeCompare
76
- * @return {-1|0|1}
87
+ * @return {number} <0: a < b, 0: a = b, >0: a > b
77
88
  */
78
89
  export function strCompare(a: string, b: string, isNumber: boolean, localeCompare = false): number {
79
90
  let _a: number | string = a;