stk-table-vue 0.0.2 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +118 -5
- package/lib/src/StkTable/StkTable.vue.d.ts +27 -2
- package/lib/src/StkTable/const.d.ts +21 -20
- package/lib/src/StkTable/types/index.d.ts +15 -2
- package/lib/src/StkTable/useKeyboardArrowScroll.d.ts +6 -3
- package/lib/stk-table-vue.js +462 -290
- package/lib/style.css +44 -10
- package/package.json +1 -1
- package/src/StkTable/StkTable.vue +171 -55
- package/src/StkTable/const.ts +1 -0
- package/src/StkTable/style.less +55 -22
- package/src/StkTable/types/index.ts +15 -2
- package/src/StkTable/useKeyboardArrowScroll.ts +24 -10
- package/src/StkTable/useVirtualScroll.ts +1 -1
- package/src/vite-env.d.ts +1 -0
package/lib/style.css
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
}
|
|
6
6
|
.stk-table{
|
|
7
7
|
--row-height:28px;
|
|
8
|
+
--header-row-height:var(--row-height);
|
|
8
9
|
--cell-padding-x:8px;
|
|
9
10
|
--resize-handle-width:4px;
|
|
10
11
|
--border-color:#e8e8f4;
|
|
@@ -25,6 +26,8 @@
|
|
|
25
26
|
--sort-arrow-active-color:#1b63d9;
|
|
26
27
|
--sort-arrow-active-sub-color:#cbcbe1;
|
|
27
28
|
--col-resize-indicator-color:#87879c;
|
|
29
|
+
--fixed-col-shadow-color-from:rgba(0, 0, 0, 0.1);
|
|
30
|
+
--fixed-col-shadow-color-to:rgba(0, 0, 0, 0);
|
|
28
31
|
position:relative;
|
|
29
32
|
overflow:auto;
|
|
30
33
|
display:flex;
|
|
@@ -45,6 +48,8 @@
|
|
|
45
48
|
--sort-arrow-active-color:#d0d1d2;
|
|
46
49
|
--sort-arrow-active-sub-color:#5d6064;
|
|
47
50
|
--col-resize-indicator-color:#5d6064;
|
|
51
|
+
--fixed-col-shadow-color-from:rgba(135, 135, 156, 0.1);
|
|
52
|
+
--fixed-col-shadow-color-to:rgba(135, 135, 156, 0);
|
|
48
53
|
color:#d1d1e0;
|
|
49
54
|
}
|
|
50
55
|
.stk-table.headless{
|
|
@@ -132,14 +137,42 @@
|
|
|
132
137
|
.stk-table .stk-table-main th,
|
|
133
138
|
.stk-table .stk-table-main td{
|
|
134
139
|
z-index:1;
|
|
135
|
-
height:var(--row-height);
|
|
136
140
|
font-size:14px;
|
|
137
141
|
box-sizing:border-box;
|
|
138
142
|
padding:0 var(--cell-padding-x);
|
|
139
143
|
}
|
|
144
|
+
.stk-table .stk-table-main th.fixed-cell--left,
|
|
145
|
+
.stk-table .stk-table-main td.fixed-cell--left{
|
|
146
|
+
--shadow-rotate:90deg;
|
|
147
|
+
}
|
|
148
|
+
.stk-table .stk-table-main th.fixed-cell--left.fixed-cell--shadow::after,
|
|
149
|
+
.stk-table .stk-table-main td.fixed-cell--left.fixed-cell--shadow::after{
|
|
150
|
+
right:-10px;
|
|
151
|
+
}
|
|
152
|
+
.stk-table .stk-table-main th.fixed-cell--right,
|
|
153
|
+
.stk-table .stk-table-main td.fixed-cell--right{
|
|
154
|
+
--shadow-rotate:-90deg;
|
|
155
|
+
}
|
|
156
|
+
.stk-table .stk-table-main th.fixed-cell--right.fixed-cell--shadow::after,
|
|
157
|
+
.stk-table .stk-table-main td.fixed-cell--right.fixed-cell--shadow::after{
|
|
158
|
+
left:-10px;
|
|
159
|
+
}
|
|
160
|
+
.stk-table .stk-table-main th.fixed-cell--shadow::after,
|
|
161
|
+
.stk-table .stk-table-main td.fixed-cell--shadow::after{
|
|
162
|
+
content:'';
|
|
163
|
+
width:10px;
|
|
164
|
+
height:100%;
|
|
165
|
+
top:0px;
|
|
166
|
+
position:absolute;
|
|
167
|
+
pointer-events:none;
|
|
168
|
+
background-image:linear-gradient(var(--shadow-rotate), var(--fixed-col-shadow-color-from), var(--fixed-col-shadow-color-to));
|
|
169
|
+
}
|
|
140
170
|
.stk-table .stk-table-main th{
|
|
141
171
|
color:var(--th-color);
|
|
142
172
|
}
|
|
173
|
+
.stk-table .stk-table-main thead tr{
|
|
174
|
+
height:var(--header-row-height);
|
|
175
|
+
}
|
|
143
176
|
.stk-table .stk-table-main thead tr:first-child th{
|
|
144
177
|
position:sticky;
|
|
145
178
|
top:0;
|
|
@@ -158,30 +191,30 @@
|
|
|
158
191
|
text-overflow:ellipsis;
|
|
159
192
|
overflow:hidden;
|
|
160
193
|
}
|
|
161
|
-
.stk-table .stk-table-main thead tr th:not(.sorter-desc):not(.sorter-asc):hover .table-header-cell-wrapper .table-header-sorter
|
|
194
|
+
.stk-table .stk-table-main thead tr th:not(.sorter-desc):not(.sorter-asc):hover .table-header-cell-wrapper .table-header-sorter .arrow-up{
|
|
162
195
|
fill:var(--sort-arrow-hover-color);
|
|
163
196
|
}
|
|
164
|
-
.stk-table .stk-table-main thead tr th:not(.sorter-desc):not(.sorter-asc):hover .table-header-cell-wrapper .table-header-sorter
|
|
197
|
+
.stk-table .stk-table-main thead tr th:not(.sorter-desc):not(.sorter-asc):hover .table-header-cell-wrapper .table-header-sorter .arrow-down{
|
|
165
198
|
fill:var(--sort-arrow-hover-color);
|
|
166
199
|
}
|
|
167
200
|
.stk-table .stk-table-main thead tr th.sorter-desc .table-header-cell-wrapper .table-header-sorter{
|
|
168
201
|
display:inline;
|
|
169
202
|
display:initial;
|
|
170
203
|
}
|
|
171
|
-
.stk-table .stk-table-main thead tr th.sorter-desc .table-header-cell-wrapper .table-header-sorter
|
|
204
|
+
.stk-table .stk-table-main thead tr th.sorter-desc .table-header-cell-wrapper .table-header-sorter .arrow-up{
|
|
172
205
|
fill:var(--sort-arrow-active-sub-color);
|
|
173
206
|
}
|
|
174
|
-
.stk-table .stk-table-main thead tr th.sorter-desc .table-header-cell-wrapper .table-header-sorter
|
|
207
|
+
.stk-table .stk-table-main thead tr th.sorter-desc .table-header-cell-wrapper .table-header-sorter .arrow-down{
|
|
175
208
|
fill:var(--sort-arrow-active-color);
|
|
176
209
|
}
|
|
177
210
|
.stk-table .stk-table-main thead tr th.sorter-asc .table-header-cell-wrapper .table-header-sorter{
|
|
178
211
|
display:inline;
|
|
179
212
|
display:initial;
|
|
180
213
|
}
|
|
181
|
-
.stk-table .stk-table-main thead tr th.sorter-asc .table-header-cell-wrapper .table-header-sorter
|
|
214
|
+
.stk-table .stk-table-main thead tr th.sorter-asc .table-header-cell-wrapper .table-header-sorter .arrow-up{
|
|
182
215
|
fill:var(--sort-arrow-active-color);
|
|
183
216
|
}
|
|
184
|
-
.stk-table .stk-table-main thead tr th.sorter-asc .table-header-cell-wrapper .table-header-sorter
|
|
217
|
+
.stk-table .stk-table-main thead tr th.sorter-asc .table-header-cell-wrapper .table-header-sorter .arrow-down{
|
|
185
218
|
fill:var(--sort-arrow-active-sub-color);
|
|
186
219
|
}
|
|
187
220
|
.stk-table .stk-table-main thead tr th .table-header-cell-wrapper{
|
|
@@ -200,8 +233,8 @@
|
|
|
200
233
|
height:16px;
|
|
201
234
|
display:none;
|
|
202
235
|
}
|
|
203
|
-
.stk-table .stk-table-main thead tr th .table-header-cell-wrapper .table-header-sorter
|
|
204
|
-
.stk-table .stk-table-main thead tr th .table-header-cell-wrapper .table-header-sorter
|
|
236
|
+
.stk-table .stk-table-main thead tr th .table-header-cell-wrapper .table-header-sorter .arrow-up,
|
|
237
|
+
.stk-table .stk-table-main thead tr th .table-header-cell-wrapper .table-header-sorter .arrow-down{
|
|
205
238
|
fill:var(--sort-arrow-color);
|
|
206
239
|
}
|
|
207
240
|
.stk-table .stk-table-main thead tr th .table-header-cell-wrapper .table-header-resizer{
|
|
@@ -219,6 +252,7 @@
|
|
|
219
252
|
}
|
|
220
253
|
.stk-table .stk-table-main tbody tr{
|
|
221
254
|
background-color:var(--td-bgc);
|
|
255
|
+
height:var(--row-height);
|
|
222
256
|
}
|
|
223
257
|
.stk-table .stk-table-main tbody tr.highlight-row{
|
|
224
258
|
animation:stkTableDim 2s linear;
|
|
@@ -265,7 +299,7 @@
|
|
|
265
299
|
}
|
|
266
300
|
.stk-table.virtual .stk-table-main thead tr th .table-header-cell-wrapper{
|
|
267
301
|
overflow:hidden;
|
|
268
|
-
max-height:var(--row-height);
|
|
302
|
+
max-height:var(--header-row-height);
|
|
269
303
|
}
|
|
270
304
|
.stk-table.virtual .stk-table-main tbody{
|
|
271
305
|
position:relative;
|
package/package.json
CHANGED
|
@@ -15,15 +15,15 @@
|
|
|
15
15
|
'border-body-v': props.bordered === 'body-v',
|
|
16
16
|
stripe: props.stripe,
|
|
17
17
|
}"
|
|
18
|
-
:style="
|
|
18
|
+
:style="
|
|
19
|
+
virtual && {
|
|
20
|
+
'--row-height': virtualScroll.rowHeight + 'px',
|
|
21
|
+
'--header-row-height': (props.headerRowHeight || props.rowHeight) + 'px',
|
|
22
|
+
}
|
|
23
|
+
"
|
|
19
24
|
@scroll="onTableScroll"
|
|
20
25
|
@wheel="onTableWheel"
|
|
21
26
|
>
|
|
22
|
-
<!-- 横向滚动时固定列的阴影,TODO: 覆盖一层在整个表上,使用linear-gradient 绘制阴影-->
|
|
23
|
-
<!-- <div
|
|
24
|
-
:class="showFixedLeftShadow && 'stk-table-fixed-left-col-box-shadow'"
|
|
25
|
-
:style="{ width: fixedLeftColWidth + 'px' }"
|
|
26
|
-
></div> -->
|
|
27
27
|
<!-- 这个元素用于虚拟滚动时,撑开父容器的高度 (已弃用,因为滚动条拖动过快,下方tr为加载出来时,会导致表头sticky闪动)
|
|
28
28
|
<div
|
|
29
29
|
v-if="virtual"
|
|
@@ -67,8 +67,7 @@
|
|
|
67
67
|
col.dataIndex === sortCol && sortOrderIndex !== 0 && 'sorter-' + sortSwitchOrder[sortOrderIndex],
|
|
68
68
|
showHeaderOverflow ? 'text-overflow' : '',
|
|
69
69
|
col.headerClassName,
|
|
70
|
-
col
|
|
71
|
-
col.fixed ? 'fixed-cell--' + col.fixed : '',
|
|
70
|
+
...getFixedColClass(col),
|
|
72
71
|
]"
|
|
73
72
|
@click="
|
|
74
73
|
e => {
|
|
@@ -83,7 +82,7 @@
|
|
|
83
82
|
<div class="table-header-cell-wrapper">
|
|
84
83
|
<component :is="col.customHeaderCell" v-if="col.customHeaderCell" :col="col" />
|
|
85
84
|
<template v-else>
|
|
86
|
-
<slot name="tableHeader" :
|
|
85
|
+
<slot name="tableHeader" :col="col">
|
|
87
86
|
<span class="table-header-title">{{ col.title }}</span>
|
|
88
87
|
</slot>
|
|
89
88
|
</template>
|
|
@@ -91,14 +90,12 @@
|
|
|
91
90
|
<!-- 排序图图标 -->
|
|
92
91
|
<span v-if="col.sorter" class="table-header-sorter">
|
|
93
92
|
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 16 16">
|
|
94
|
-
<
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
></polygon>
|
|
101
|
-
</g>
|
|
93
|
+
<polygon class="arrow-up" fill="#757699" points="8 2 4.8 6 11.2 6"></polygon>
|
|
94
|
+
<polygon
|
|
95
|
+
class="arrow-down"
|
|
96
|
+
transform="translate(8, 12) rotate(-180) translate(-8, -12) "
|
|
97
|
+
points="8 10 4.8 14 11.2 14"
|
|
98
|
+
></polygon>
|
|
102
99
|
</svg>
|
|
103
100
|
</span>
|
|
104
101
|
<!-- 列宽拖动handler -->
|
|
@@ -164,12 +161,7 @@
|
|
|
164
161
|
v-for="col in virtualX_columnPart"
|
|
165
162
|
:key="col.dataIndex"
|
|
166
163
|
:data-index="col.dataIndex"
|
|
167
|
-
:class="[
|
|
168
|
-
col.className,
|
|
169
|
-
showOverflow ? 'text-overflow' : '',
|
|
170
|
-
col.fixed ? 'fixed-cell' : '',
|
|
171
|
-
col.fixed ? 'fixed-cell--' + col.fixed : '',
|
|
172
|
-
]"
|
|
164
|
+
:class="[col.className, showOverflow ? 'text-overflow' : '', ...getFixedColClass(col)]"
|
|
173
165
|
:style="getCellStyle(2, col)"
|
|
174
166
|
@click="e => onCellClick(e, row, col)"
|
|
175
167
|
>
|
|
@@ -188,7 +180,7 @@
|
|
|
188
180
|
</div>
|
|
189
181
|
</template>
|
|
190
182
|
|
|
191
|
-
<script setup lang="
|
|
183
|
+
<script setup lang="tsx">
|
|
192
184
|
/**
|
|
193
185
|
* @author JA+
|
|
194
186
|
* 不支持低版本浏览器非虚拟滚动表格的表头固定,列固定,因为会卡。
|
|
@@ -197,7 +189,8 @@
|
|
|
197
189
|
* [] 计算的高亮颜色,挂在数据源上对象上,若多个表格使用同一个数据源对象会有问题。需要深拷贝。(解决方案:获取组件uid)
|
|
198
190
|
* [] highlight-row 颜色不能恢复到active的颜色
|
|
199
191
|
*/
|
|
200
|
-
import { CSSProperties, onMounted, ref, shallowRef, toRaw, watch } from 'vue';
|
|
192
|
+
import { CSSProperties, VNode, onMounted, ref, shallowRef, toRaw, watch } from 'vue';
|
|
193
|
+
import { Default_Row_Height } from './const';
|
|
201
194
|
import { Order, SortOption, StkTableColumn, UniqKey } from './types/index';
|
|
202
195
|
import { useAutoResize } from './useAutoResize';
|
|
203
196
|
import { useColResize } from './useColResize';
|
|
@@ -230,14 +223,16 @@ const props = withDefaults(
|
|
|
230
223
|
theme?: 'light' | 'dark';
|
|
231
224
|
/** 行高 */
|
|
232
225
|
rowHeight?: number;
|
|
226
|
+
/** 表头行高。default = rowHeight */
|
|
227
|
+
headerRowHeight?: number | null;
|
|
233
228
|
/** 虚拟滚动 */
|
|
234
229
|
virtual?: boolean;
|
|
235
230
|
/** x轴虚拟滚动 */
|
|
236
231
|
virtualX?: boolean;
|
|
237
232
|
/** 表格列配置 */
|
|
238
|
-
columns?: StkTableColumn<
|
|
233
|
+
columns?: StkTableColumn<DT>[];
|
|
239
234
|
/** 表格数据源 */
|
|
240
|
-
dataSource?:
|
|
235
|
+
dataSource?: DT[];
|
|
241
236
|
/** 行唯一键 */
|
|
242
237
|
rowKey?: UniqKey;
|
|
243
238
|
/** 列唯一键 */
|
|
@@ -285,6 +280,8 @@ const props = withDefaults(
|
|
|
285
280
|
* 传入方法表示resize后的回调
|
|
286
281
|
*/
|
|
287
282
|
autoResize?: boolean | (() => void);
|
|
283
|
+
/** 是否展示固定列阴影。默认不展示。 */
|
|
284
|
+
fixedColShadow?: boolean;
|
|
288
285
|
}>(),
|
|
289
286
|
{
|
|
290
287
|
width: '',
|
|
@@ -294,7 +291,8 @@ const props = withDefaults(
|
|
|
294
291
|
maxWidth: '',
|
|
295
292
|
headless: false,
|
|
296
293
|
theme: 'light',
|
|
297
|
-
rowHeight:
|
|
294
|
+
rowHeight: Default_Row_Height,
|
|
295
|
+
headerRowHeight: null,
|
|
298
296
|
virtual: false,
|
|
299
297
|
virtualX: false,
|
|
300
298
|
columns: () => [],
|
|
@@ -314,39 +312,88 @@ const props = withDefaults(
|
|
|
314
312
|
colMinWidth: 10,
|
|
315
313
|
bordered: true,
|
|
316
314
|
autoResize: true,
|
|
315
|
+
fixedColShadow: false,
|
|
317
316
|
},
|
|
318
317
|
);
|
|
319
318
|
|
|
320
319
|
const emits = defineEmits<{
|
|
321
|
-
/**
|
|
320
|
+
/**
|
|
321
|
+
* 排序变更触发
|
|
322
|
+
* ```(col: StkTableColumn<DT>, order: Order, data: DT[])```
|
|
323
|
+
*/
|
|
322
324
|
(e: 'sort-change', col: StkTableColumn<DT>, order: Order, data: DT[]): void;
|
|
323
|
-
/**
|
|
325
|
+
/**
|
|
326
|
+
* 一行点击事件
|
|
327
|
+
* ```(ev: MouseEvent, row: DT)```
|
|
328
|
+
*/
|
|
324
329
|
(e: 'row-click', ev: MouseEvent, row: DT): void;
|
|
325
|
-
/**
|
|
330
|
+
/**
|
|
331
|
+
* 选中一行触发。ev返回null表示不是点击事件触发的
|
|
332
|
+
* ```(ev: MouseEvent | null, row: DT)```
|
|
333
|
+
*/
|
|
326
334
|
(e: 'current-change', ev: MouseEvent | null, row: DT): void;
|
|
327
|
-
/**
|
|
335
|
+
/**
|
|
336
|
+
* 行双击事件
|
|
337
|
+
* ```(ev: MouseEvent, row: DT)```
|
|
338
|
+
*/
|
|
328
339
|
(e: 'row-dblclick', ev: MouseEvent, row: DT): void;
|
|
329
|
-
/**
|
|
340
|
+
/**
|
|
341
|
+
* 表头右键事件
|
|
342
|
+
* ```(ev: MouseEvent)```
|
|
343
|
+
*/
|
|
330
344
|
(e: 'header-row-menu', ev: MouseEvent): void;
|
|
331
|
-
/**
|
|
345
|
+
/**
|
|
346
|
+
* 表体行右键点击事件
|
|
347
|
+
* ```(ev: MouseEvent, row: DT)```
|
|
348
|
+
*/
|
|
332
349
|
(e: 'row-menu', ev: MouseEvent, row: DT): void;
|
|
333
|
-
/**
|
|
350
|
+
/**
|
|
351
|
+
* 单元格点击事件
|
|
352
|
+
* ```(ev: MouseEvent, row: DT, col: StkTableColumn<DT>)```
|
|
353
|
+
*/
|
|
334
354
|
(e: 'cell-click', ev: MouseEvent, row: DT, col: StkTableColumn<DT>): void;
|
|
335
|
-
|
|
355
|
+
/**
|
|
356
|
+
* 表头单元格点击事件
|
|
357
|
+
* ```(ev: MouseEvent, col: StkTableColumn<DT>)```
|
|
358
|
+
*/
|
|
336
359
|
(e: 'header-cell-click', ev: MouseEvent, col: StkTableColumn<DT>): void;
|
|
337
|
-
/**
|
|
360
|
+
/**
|
|
361
|
+
* 表格滚动事件
|
|
362
|
+
* ```(ev: Event, data: { startIndex: number; endIndex: number })```
|
|
363
|
+
*/
|
|
338
364
|
(e: 'scroll', ev: Event, data: { startIndex: number; endIndex: number }): void;
|
|
339
|
-
/**
|
|
365
|
+
/**
|
|
366
|
+
* 表格横向滚动事件
|
|
367
|
+
* ```(ev: Event)```
|
|
368
|
+
*/
|
|
340
369
|
(e: 'scroll-x', ev: Event): void;
|
|
341
|
-
/**
|
|
370
|
+
/**
|
|
371
|
+
* 表头列拖动事件
|
|
372
|
+
* ```(dragStartKey: string, targetColKey: string)```
|
|
373
|
+
*/
|
|
342
374
|
(e: 'col-order-change', dragStartKey: string, targetColKey: string): void;
|
|
343
|
-
/**
|
|
375
|
+
/**
|
|
376
|
+
* 表头列拖动开始
|
|
377
|
+
* ```(dragStartKey: string)```
|
|
378
|
+
*/
|
|
344
379
|
(e: 'th-drag-start', dragStartKey: string): void;
|
|
345
|
-
/**
|
|
380
|
+
/**
|
|
381
|
+
* 表头列拖动drop
|
|
382
|
+
* ```(targetColKey: string)```
|
|
383
|
+
*/
|
|
346
384
|
(e: 'th-drop', targetColKey: string): void;
|
|
385
|
+
/** v-model:columns col resize 时更新宽度*/
|
|
347
386
|
(e: 'update:columns', cols: StkTableColumn<DT>[]): void;
|
|
348
387
|
}>();
|
|
349
388
|
|
|
389
|
+
// 仅支持vue3.3+
|
|
390
|
+
// const slots = defineSlots<{
|
|
391
|
+
// /** 表头插槽 */
|
|
392
|
+
// tableHeader(props: { col: StkTableColumn<DT> }): void;
|
|
393
|
+
// /** 空状态插槽 */
|
|
394
|
+
// empty(): void;
|
|
395
|
+
// }>();
|
|
396
|
+
|
|
350
397
|
const tableContainer = ref<HTMLDivElement>();
|
|
351
398
|
const colResizeIndicator = ref<HTMLDivElement>();
|
|
352
399
|
/** 当前选中的一行*/
|
|
@@ -376,7 +423,17 @@ const tableHeaders = ref<StkTableColumn<DT>[][]>([]);
|
|
|
376
423
|
/** 若有多级表头时,最后一行的tableHeaders.内容是 props.columns 的引用集合 */
|
|
377
424
|
const tableHeaderLast = ref<StkTableColumn<DT>[]>([]);
|
|
378
425
|
|
|
379
|
-
const dataSourceCopy = shallowRef([...props.dataSource]);
|
|
426
|
+
const dataSourceCopy = shallowRef<DT[]>([...props.dataSource]);
|
|
427
|
+
|
|
428
|
+
/** 固定列阴影 */
|
|
429
|
+
const fixedShadow = ref({
|
|
430
|
+
/** 是否展示左侧固定列阴影 */
|
|
431
|
+
showL: false,
|
|
432
|
+
/** 是否展示右侧固定列阴影 */
|
|
433
|
+
showR: false,
|
|
434
|
+
/** 保存需要出现阴影的列 */
|
|
435
|
+
cols: [] as StkTableColumn<DT>[],
|
|
436
|
+
});
|
|
380
437
|
|
|
381
438
|
/**高亮帧间隔
|
|
382
439
|
const highlightStepDuration = Highlight_Color_Change_Freq / 1000 + 's';*/
|
|
@@ -431,9 +488,11 @@ if (props.autoResize) {
|
|
|
431
488
|
|
|
432
489
|
/** 键盘箭头滚动 */
|
|
433
490
|
useKeyboardArrowScroll(tableContainer, {
|
|
491
|
+
props,
|
|
434
492
|
scrollTo,
|
|
435
493
|
virtualScroll,
|
|
436
494
|
virtualScrollX,
|
|
495
|
+
tableHeaders,
|
|
437
496
|
});
|
|
438
497
|
|
|
439
498
|
watch(
|
|
@@ -453,7 +512,6 @@ watch(
|
|
|
453
512
|
console.warn('invalid dataSource');
|
|
454
513
|
return;
|
|
455
514
|
}
|
|
456
|
-
// dealColumns(val);
|
|
457
515
|
let needInitVirtualScrollY = false;
|
|
458
516
|
if (dataSourceCopy.value.length !== val.length) {
|
|
459
517
|
needInitVirtualScrollY = true;
|
|
@@ -467,6 +525,7 @@ watch(
|
|
|
467
525
|
const column = tableHeaderLast.value.find(it => it.dataIndex === sortCol.value);
|
|
468
526
|
onColumnSort(column, false);
|
|
469
527
|
}
|
|
528
|
+
updateFixedShadow();
|
|
470
529
|
},
|
|
471
530
|
{
|
|
472
531
|
deep: false,
|
|
@@ -474,11 +533,11 @@ watch(
|
|
|
474
533
|
);
|
|
475
534
|
onMounted(() => {
|
|
476
535
|
initVirtualScroll();
|
|
536
|
+
updateFixedShadow();
|
|
477
537
|
});
|
|
478
538
|
|
|
479
539
|
/**
|
|
480
540
|
* 处理多级表头
|
|
481
|
-
* FIXME: 仅支持到两级表头。不支持多级。
|
|
482
541
|
*/
|
|
483
542
|
function dealColumns() {
|
|
484
543
|
// reset
|
|
@@ -497,9 +556,10 @@ function dealColumns() {
|
|
|
497
556
|
/**
|
|
498
557
|
* @param arr
|
|
499
558
|
* @param depth 深度
|
|
559
|
+
* @param parent 父节点引用,用于构建双向链表。
|
|
500
560
|
* @param parentFixed 父节点固定列继承。
|
|
501
561
|
*/
|
|
502
|
-
function flat(arr: StkTableColumn<
|
|
562
|
+
function flat(arr: StkTableColumn<DT>[], parent: StkTableColumn<DT> | null, depth = 0 /* , parentFixed: 'left' | 'right' | null = null */) {
|
|
503
563
|
if (!tableHeaders.value[depth]) {
|
|
504
564
|
tableHeaders.value[depth] = [];
|
|
505
565
|
}
|
|
@@ -510,11 +570,13 @@ function dealColumns() {
|
|
|
510
570
|
// if (parentFixed) {
|
|
511
571
|
// col.fixed = parentFixed;
|
|
512
572
|
// }
|
|
573
|
+
// 构建指向父节点的引用
|
|
574
|
+
col.__PARENT__ = parent;
|
|
513
575
|
/** 一列中的子节点数量 */
|
|
514
576
|
let colChildrenLen = 1;
|
|
515
577
|
if (col.children) {
|
|
516
578
|
// DFS
|
|
517
|
-
colChildrenLen = flat(col.children, depth + 1 /* , col.fixed */);
|
|
579
|
+
colChildrenLen = flat(col.children, col, depth + 1 /* , col.fixed */);
|
|
518
580
|
} else {
|
|
519
581
|
tempHeaderLast.push(col); // 没有children的列作为colgroup
|
|
520
582
|
}
|
|
@@ -532,15 +594,58 @@ function dealColumns() {
|
|
|
532
594
|
});
|
|
533
595
|
return allChildrenLen;
|
|
534
596
|
}
|
|
535
|
-
|
|
597
|
+
|
|
598
|
+
flat(copyColumn, null);
|
|
536
599
|
|
|
537
600
|
tableHeaderLast.value = tempHeaderLast;
|
|
601
|
+
dealFixedColShadow();
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/** 处理固定列阴影 */
|
|
605
|
+
function dealFixedColShadow() {
|
|
606
|
+
if (!props.fixedColShadow) return;
|
|
607
|
+
fixedShadow.value.cols = [];
|
|
608
|
+
const lastLeftCol = tableHeaderLast.value.findLast(it => it.fixed === 'left');
|
|
609
|
+
const lastRightCol = tableHeaderLast.value.find(it => it.fixed === 'right');
|
|
610
|
+
// 处理多级表头列阴影
|
|
611
|
+
let node: any = { __PARENT__: lastLeftCol };
|
|
612
|
+
while ((node = node.__PARENT__)) {
|
|
613
|
+
if (node.fixed) {
|
|
614
|
+
fixedShadow.value.cols.push(node);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
node = { __PARENT__: lastRightCol };
|
|
618
|
+
while ((node = node.__PARENT__)) {
|
|
619
|
+
if (node.fixed) {
|
|
620
|
+
fixedShadow.value.cols.push(node);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
/** 固定列class */
|
|
626
|
+
function getFixedColClass(col: StkTableColumn<DT>): string[] {
|
|
627
|
+
const { showR, showL, cols } = fixedShadow.value;
|
|
628
|
+
const classArr = [
|
|
629
|
+
col.fixed ? 'fixed-cell' : '',
|
|
630
|
+
col.fixed ? 'fixed-cell--' + col.fixed : '',
|
|
631
|
+
props.fixedColShadow && col.fixed && ((showL && col.fixed === 'left') || (showR && col.fixed === 'right')) && cols.includes(col)
|
|
632
|
+
? 'fixed-cell--shadow'
|
|
633
|
+
: '',
|
|
634
|
+
];
|
|
635
|
+
return classArr;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
function updateFixedShadow() {
|
|
639
|
+
if (!props.fixedColShadow) return;
|
|
640
|
+
const { clientWidth, scrollWidth, scrollLeft } = tableContainer.value as HTMLDivElement;
|
|
641
|
+
fixedShadow.value.showL = Boolean(scrollLeft);
|
|
642
|
+
fixedShadow.value.showR = Math.abs(scrollWidth - scrollLeft - clientWidth) > 0.5;
|
|
538
643
|
}
|
|
539
644
|
|
|
540
645
|
/**
|
|
541
646
|
* 行唯一值生成
|
|
542
647
|
*/
|
|
543
|
-
function rowKeyGen(row:
|
|
648
|
+
function rowKeyGen(row: DT) {
|
|
544
649
|
let key = rowKeyGenStore.get(row);
|
|
545
650
|
if (!key) {
|
|
546
651
|
key = typeof props.rowKey === 'function' ? props.rowKey(row) : row[props.rowKey];
|
|
@@ -678,10 +783,12 @@ function onTableWheel(e: MouseEvent) {
|
|
|
678
783
|
function onTableScroll(e: Event) {
|
|
679
784
|
if (!e?.target) return;
|
|
680
785
|
|
|
681
|
-
// 此处可优化,因为访问e.target.scrollXX消耗性能
|
|
682
786
|
const { scrollTop, scrollLeft } = e.target as HTMLElement;
|
|
683
|
-
const
|
|
684
|
-
const
|
|
787
|
+
const { scrollTop: vScrollTop, startIndex, endIndex } = virtualScroll.value;
|
|
788
|
+
const { scrollLeft: vScrollLeft } = virtualScrollX.value;
|
|
789
|
+
const isYScroll = scrollTop !== vScrollTop;
|
|
790
|
+
const isXScroll = scrollLeft !== vScrollLeft;
|
|
791
|
+
|
|
685
792
|
// 纵向滚动有变化
|
|
686
793
|
if (isYScroll) {
|
|
687
794
|
virtualScroll.value.scrollTop = scrollTop;
|
|
@@ -693,14 +800,12 @@ function onTableScroll(e: Event) {
|
|
|
693
800
|
// 横向滚动有变化
|
|
694
801
|
if (isXScroll) {
|
|
695
802
|
virtualScrollX.value.scrollLeft = scrollLeft;
|
|
803
|
+
updateFixedShadow();
|
|
696
804
|
}
|
|
697
805
|
if (virtualX_on.value) {
|
|
698
806
|
updateVirtualScrollX(scrollLeft);
|
|
699
807
|
}
|
|
700
|
-
const data = {
|
|
701
|
-
startIndex: virtualScroll.value.startIndex,
|
|
702
|
-
endIndex: virtualScroll.value.endIndex,
|
|
703
|
-
};
|
|
808
|
+
const data = { startIndex, endIndex };
|
|
704
809
|
if (isYScroll) {
|
|
705
810
|
emits('scroll', e, data);
|
|
706
811
|
}
|
|
@@ -775,16 +880,27 @@ function getTableData() {
|
|
|
775
880
|
}
|
|
776
881
|
|
|
777
882
|
defineExpose({
|
|
883
|
+
/** 初始化横向纵向虚拟滚动 */
|
|
778
884
|
initVirtualScroll,
|
|
885
|
+
/** 初始化横向虚拟滚动 */
|
|
779
886
|
initVirtualScrollX,
|
|
887
|
+
/** 初始化纵向虚拟滚动 */
|
|
780
888
|
initVirtualScrollY,
|
|
889
|
+
/** 设置当前选中行 */
|
|
781
890
|
setCurrentRow,
|
|
891
|
+
/** 设置高亮渐暗单元格 */
|
|
782
892
|
setHighlightDimCell,
|
|
893
|
+
/** 设置高亮渐暗行 */
|
|
783
894
|
setHighlightDimRow,
|
|
895
|
+
/** 表格排序列dataIndex */
|
|
784
896
|
sortCol,
|
|
897
|
+
/** 设置排序 */
|
|
785
898
|
setSorter,
|
|
899
|
+
/** 重置排序 */
|
|
786
900
|
resetSorter,
|
|
901
|
+
/** 滚动至 */
|
|
787
902
|
scrollTo,
|
|
903
|
+
/** 获取表格数据 */
|
|
788
904
|
getTableData,
|
|
789
905
|
});
|
|
790
906
|
</script>
|