stk-table-vue 0.3.1 → 0.3.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/lib/style.css CHANGED
@@ -11,6 +11,7 @@
11
11
  --border-color:#e8e8f4;
12
12
  --border-width:1px;
13
13
  --td-bgc:#fff;
14
+ --td-hover-color:#71a2fd;
14
15
  --th-bgc:#fafafc;
15
16
  --th-color:#272841;
16
17
  --tr-active-bgc:#e6f7ff;
@@ -44,6 +45,7 @@
44
45
  --th-bgc:#202029;
45
46
  --th-color:#C0C0D1;
46
47
  --td-bgc:#1b1b24;
48
+ --td-hover-color:#70a6ff;
47
49
  --border-color:#292933;
48
50
  --tr-active-bgc:#283f63;
49
51
  --tr-hover-bgc:#1a2b46;
@@ -86,23 +88,109 @@
86
88
  .stk-table.border thead tr:first-child th{
87
89
  background-image:var(--bg-border-top), var(--bg-border-right), var(--bg-border-bottom);
88
90
  }
89
- .stk-table.border.virtual-x .virtual-x-left{
90
- background:none;
91
- pointer-events:none;
92
- }
93
- .stk-table.border.virtual-x .virtual-x-right{
94
- padding:0;
95
- background:none;
96
- pointer-events:none;
97
- }
98
91
  .stk-table.border-body-v tbody{
99
92
  --bg-border-bottom:linear-gradient(transparent, transparent);
100
93
  }
101
- .stk-table.stripe{
102
- }
103
94
  .stk-table.stripe tbody tr:nth-child(odd){
104
95
  background-color:var(--stripe-bgc);
105
96
  }
97
+ .stk-table.cell-hover tbody td:hover{
98
+ box-shadow:inset 0 0 0 2px var(--td-hover-color);
99
+ }
100
+ .stk-table.text-overflow .table-cell-wrapper{
101
+ white-space:nowrap;
102
+ overflow:hidden;
103
+ text-overflow:ellipsis;
104
+ }
105
+ .stk-table.header-text-overflow .table-header-cell-wrapper{
106
+ white-space:nowrap;
107
+ overflow:hidden;
108
+ }
109
+ .stk-table.header-text-overflow .table-header-title{
110
+ text-overflow:ellipsis;
111
+ overflow:hidden;
112
+ }
113
+ .stk-table.virtual{
114
+ }
115
+ .stk-table.virtual .table-header-cell-wrapper{
116
+ overflow:hidden;
117
+ max-height:var(--header-row-height);
118
+ }
119
+ .stk-table.virtual tbody td{
120
+ height:var(--row-height);
121
+ line-height:1;
122
+ }
123
+ .stk-table.virtual tbody td .table-cell-wrapper{
124
+ max-height:var(--row-height);
125
+ overflow:hidden;
126
+ }
127
+ .stk-table.virtual .padding-top-tr td{
128
+ height:0;
129
+ }
130
+ .stk-table th,
131
+ .stk-table td{
132
+ z-index:1;
133
+ font-size:14px;
134
+ box-sizing:border-box;
135
+ padding:0 var(--cell-padding-x);
136
+ }
137
+ .stk-table th{
138
+ color:var(--th-color);
139
+ background-color:inherit;
140
+ }
141
+ .stk-table th.sortable{
142
+ cursor:pointer;
143
+ }
144
+ .stk-table th:not(.sorter-desc):not(.sorter-asc):hover .table-header-sorter .arrow-up{
145
+ fill:var(--sort-arrow-hover-color);
146
+ }
147
+ .stk-table th:not(.sorter-desc):not(.sorter-asc):hover .table-header-sorter .arrow-down{
148
+ fill:var(--sort-arrow-hover-color);
149
+ }
150
+ .stk-table th.sorter-desc .table-header-sorter{
151
+ display:inline;
152
+ display:initial;
153
+ }
154
+ .stk-table th.sorter-desc .table-header-sorter .arrow-up{
155
+ fill:var(--sort-arrow-active-sub-color);
156
+ }
157
+ .stk-table th.sorter-desc .table-header-sorter .arrow-down{
158
+ fill:var(--sort-arrow-active-color);
159
+ }
160
+ .stk-table th.sorter-asc .table-header-sorter{
161
+ display:inline;
162
+ display:initial;
163
+ }
164
+ .stk-table th.sorter-asc .table-header-sorter .arrow-up{
165
+ fill:var(--sort-arrow-active-color);
166
+ }
167
+ .stk-table th.sorter-asc .table-header-sorter .arrow-down{
168
+ fill:var(--sort-arrow-active-sub-color);
169
+ }
170
+ .stk-table thead tr{
171
+ background-color:var(--th-bgc);
172
+ height:var(--header-row-height);
173
+ }
174
+ .stk-table thead tr:first-child th{
175
+ position:sticky;
176
+ top:0;
177
+ }
178
+ .stk-table .stk-table-main tbody tr{
179
+ background-color:var(--td-bgc);
180
+ height:var(--row-height);
181
+ }
182
+ .stk-table .stk-table-main tbody tr:hover{
183
+ background-color:var(--tr-hover-bgc);
184
+ }
185
+ .stk-table .stk-table-main tbody tr.active{
186
+ background-color:var(--tr-active-bgc);
187
+ }
188
+ .stk-table .virtual-x-left,
189
+ .stk-table .virtual-x-right{
190
+ padding:0;
191
+ background:none;
192
+ pointer-events:none;
193
+ }
106
194
  .stk-table .column-resize-indicator{
107
195
  width:0;
108
196
  height:100%;
@@ -124,56 +212,29 @@
124
212
  min-width:-moz-min-content;
125
213
  min-width:min-content;
126
214
  }
127
- .stk-table .stk-table-main th,
128
- .stk-table .stk-table-main td{
129
- z-index:1;
130
- font-size:14px;
131
- box-sizing:border-box;
132
- padding:0 var(--cell-padding-x);
133
- }
134
- .stk-table .stk-table-main th{
135
- color:var(--th-color);
136
- background-color:var(--th-bgc);
137
- }
138
- .stk-table .stk-table-main th.sortable{
139
- cursor:pointer;
140
- }
141
- .stk-table .stk-table-main th.text-overflow .table-header-cell-wrapper{
142
- white-space:nowrap;
143
- overflow:hidden;
144
- }
145
- .stk-table .stk-table-main th.text-overflow .table-header-title{
146
- text-overflow:ellipsis;
147
- overflow:hidden;
148
- }
149
- .stk-table .stk-table-main td.fixed-cell{
215
+ .stk-table .fixed-cell{
150
216
  background-color:inherit;
151
217
  }
152
- .stk-table .stk-table-main td.highlight-cell{
218
+ .stk-table .highlight-cell{
153
219
  animation:stk-table-dim var(--highlight-duration);
154
220
  animation-timing-function:var(--highlight-timing-function);
155
221
  }
156
- .stk-table .stk-table-main td.text-overflow .table-cell-wrapper{
157
- white-space:nowrap;
158
- overflow:hidden;
159
- text-overflow:ellipsis;
160
- }
161
- .stk-table .stk-table-main td.seq-column{
222
+ .stk-table .seq-column{
162
223
  text-align:center;
163
224
  }
164
- .stk-table .stk-table-main .fixed-cell--left{
225
+ .stk-table .fixed-cell--left{
165
226
  --shadow-rotate:90deg;
166
227
  }
167
- .stk-table .stk-table-main .fixed-cell--left.fixed-cell--shadow::after{
228
+ .stk-table .fixed-cell--left.fixed-cell--shadow::after{
168
229
  right:-10px;
169
230
  }
170
- .stk-table .stk-table-main .fixed-cell--right{
231
+ .stk-table .fixed-cell--right{
171
232
  --shadow-rotate:-90deg;
172
233
  }
173
- .stk-table .stk-table-main .fixed-cell--right.fixed-cell--shadow::after{
234
+ .stk-table .fixed-cell--right.fixed-cell--shadow::after{
174
235
  left:-10px;
175
236
  }
176
- .stk-table .stk-table-main .fixed-cell--shadow::after{
237
+ .stk-table .fixed-cell--shadow::after{
177
238
  content:'';
178
239
  width:10px;
179
240
  height:100%;
@@ -182,88 +243,43 @@
182
243
  pointer-events:none;
183
244
  background-image:linear-gradient(var(--shadow-rotate), var(--fixed-col-shadow-color-from), var(--fixed-col-shadow-color-to));
184
245
  }
185
- .stk-table .stk-table-main thead tr{
186
- height:var(--header-row-height);
187
- }
188
- .stk-table .stk-table-main thead tr:first-child th{
189
- position:sticky;
190
- top:0;
191
- }
192
- .stk-table .stk-table-main th:not(.sorter-desc):not(.sorter-asc):hover .table-header-sorter .arrow-up{
193
- fill:var(--sort-arrow-hover-color);
194
- }
195
- .stk-table .stk-table-main th:not(.sorter-desc):not(.sorter-asc):hover .table-header-sorter .arrow-down{
196
- fill:var(--sort-arrow-hover-color);
197
- }
198
- .stk-table .stk-table-main th.sorter-desc .table-header-sorter{
199
- display:inline;
200
- display:initial;
201
- }
202
- .stk-table .stk-table-main th.sorter-desc .table-header-sorter .arrow-up{
203
- fill:var(--sort-arrow-active-sub-color);
204
- }
205
- .stk-table .stk-table-main th.sorter-desc .table-header-sorter .arrow-down{
206
- fill:var(--sort-arrow-active-color);
207
- }
208
- .stk-table .stk-table-main th.sorter-asc .table-header-sorter{
209
- display:inline;
210
- display:initial;
211
- }
212
- .stk-table .stk-table-main th.sorter-asc .table-header-sorter .arrow-up{
213
- fill:var(--sort-arrow-active-color);
214
- }
215
- .stk-table .stk-table-main th.sorter-asc .table-header-sorter .arrow-down{
216
- fill:var(--sort-arrow-active-sub-color);
217
- }
218
- .stk-table .stk-table-main .table-header-cell-wrapper{
246
+ .stk-table .table-header-cell-wrapper{
219
247
  max-width:100%;
220
248
  display:inline-flex;
221
249
  align-items:center;
222
250
  }
223
- .stk-table .stk-table-main .table-header-title{
251
+ .stk-table .table-header-title{
224
252
  overflow:hidden;
225
253
  align-self:flex-start;
226
254
  }
227
- .stk-table .stk-table-main .table-header-sorter{
255
+ .stk-table .table-header-sorter{
228
256
  flex-shrink:0;
229
257
  margin-left:4px;
230
258
  width:16px;
231
259
  height:16px;
232
260
  display:none;
233
261
  }
234
- .stk-table .stk-table-main .table-header-sorter .arrow-up,
235
- .stk-table .stk-table-main .table-header-sorter .arrow-down{
262
+ .stk-table .table-header-sorter .arrow-up,
263
+ .stk-table .table-header-sorter .arrow-down{
236
264
  fill:var(--sort-arrow-color);
237
265
  }
238
- .stk-table .stk-table-main .table-header-resizer{
266
+ .stk-table .table-header-resizer{
239
267
  position:absolute;
240
268
  top:0;
241
269
  bottom:0;
242
270
  cursor:col-resize;
243
271
  width:var(--resize-handle-width);
244
272
  }
245
- .stk-table .stk-table-main .table-header-resizer.left{
273
+ .stk-table .table-header-resizer.left{
246
274
  left:0;
247
275
  }
248
- .stk-table .stk-table-main .table-header-resizer.right{
276
+ .stk-table .table-header-resizer.right{
249
277
  right:0;
250
278
  }
251
- .stk-table .stk-table-main tbody tr{
252
- background-color:var(--td-bgc);
253
- height:var(--row-height);
254
- transform:translateZ(0);
255
- }
256
- .stk-table .stk-table-main tbody tr.highlight-row{
279
+ .stk-table .highlight-row{
257
280
  animation:stk-table-dim var(--highlight-duration);
258
281
  animation-timing-function:var(--highlight-timing-function);
259
282
  }
260
- .stk-table .stk-table-main tbody tr.hover,
261
- .stk-table .stk-table-main tbody tr:hover{
262
- background-color:var(--tr-hover-bgc);
263
- }
264
- .stk-table .stk-table-main tbody tr.active{
265
- background-color:var(--tr-active-bgc);
266
- }
267
283
  .stk-table .stk-table-no-data{
268
284
  background-color:var(--table-bgc);
269
285
  line-height:var(--row-height);
@@ -281,26 +297,3 @@
281
297
  .stk-table .stk-table-no-data.no-data-full{
282
298
  flex:1;
283
299
  }
284
- .stk-table.virtual{
285
- }
286
- .stk-table.virtual .table-header-cell-wrapper{
287
- overflow:hidden;
288
- max-height:var(--header-row-height);
289
- }
290
- .stk-table.virtual tbody{
291
- position:relative;
292
- }
293
- .stk-table.virtual tbody tr td{
294
- height:var(--row-height);
295
- line-height:1;
296
- }
297
- .stk-table.virtual tbody tr td .table-cell-wrapper{
298
- max-height:var(--row-height);
299
- overflow:hidden;
300
- }
301
- .stk-table.virtual .padding-top-tr td{
302
- height:0;
303
- }
304
- .stk-table.virtual-x .virtual-x-left{
305
- padding:0;
306
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stk-table-vue",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "Simple realtime virtual table for vue3&vue2.7",
5
5
  "main": "./lib/stk-table-vue.js",
6
6
  "types": "./lib/src/StkTable/index.d.ts",
@@ -14,6 +14,9 @@
14
14
  'border-v': props.bordered === 'v',
15
15
  'border-body-v': props.bordered === 'body-v',
16
16
  stripe: props.stripe,
17
+ 'cell-hover': props.cellHover,
18
+ 'text-overflow': props.showOverflow,
19
+ 'header-text-overflow': props.showHeaderOverflow,
17
20
  }"
18
21
  :style="[
19
22
  virtual && {
@@ -69,7 +72,6 @@
69
72
  :class="[
70
73
  col.sorter ? 'sortable' : '',
71
74
  col.dataIndex === sortCol && sortOrderIndex !== 0 && 'sorter-' + sortSwitchOrder[sortOrderIndex],
72
- showHeaderOverflow ? 'text-overflow' : '',
73
75
  col.headerClassName,
74
76
  fixedColClassMap.get(colKeyGen(col)),
75
77
  ]"
@@ -140,7 +142,7 @@
140
142
  <tbody>
141
143
  <tr v-if="virtual_on" :style="{ height: `${virtualScroll.offsetTop}px` }" class="padding-top-tr">
142
144
  <!--这个td用于配合虚拟滚动的th对应,防止列错位-->
143
- <td v-if="virtualX_on && fixedMode && headless" class="virtual-x-left" style="padding: 0"></td>
145
+ <td v-if="virtualX_on && fixedMode && headless" class="virtual-x-left"></td>
144
146
  <template v-if="fixedMode && headless">
145
147
  <td v-for="col in virtualX_columnPart" :key="col.dataIndex" :style="cellStyleMap[TagType.TD].get(colKeyGen(col))"></td
146
148
  ></template>
@@ -151,8 +153,8 @@
151
153
  :key="rowKey ? rowKeyGen(row) : rowIndex"
152
154
  :data-row-key="rowKey ? rowKeyGen(row) : rowIndex"
153
155
  :class="{
154
- active: rowKey ? rowKeyGen(row) === rowKeyGen(currentItem) : row === currentItem,
155
- hover: rowKey ? rowKeyGen(row) === currentHover : row === currentHover,
156
+ active: rowKey ? rowKeyGen(row) === rowKeyGen(currentRow) : row === currentRow,
157
+ hover: props.showTrHoverClass && (rowKey ? rowKeyGen(row) === currentHoverRowKey : row === currentHoverRowKey),
156
158
  [rowClassName(row, rowIndex)]: true,
157
159
  }"
158
160
  @click="e => onRowClick(e, row)"
@@ -161,19 +163,17 @@
161
163
  @mouseover="e => onTrMouseOver(e, row)"
162
164
  >
163
165
  <!--这个td用于配合虚拟滚动的th对应,防止列错位-->
164
- <td v-if="virtualX_on" class="virtual-x-left" style="padding: 0"></td>
166
+ <td v-if="virtualX_on" class="virtual-x-left"></td>
165
167
  <td
166
168
  v-for="(col, colIndex) in virtualX_columnPart"
167
169
  :key="col.dataIndex"
168
170
  :data-index="col.dataIndex"
169
- :class="[
170
- col.className,
171
- fixedColClassMap.get(colKeyGen(col)),
172
- showOverflow ? 'text-overflow' : '',
173
- col.type === 'seq' ? 'seq-column' : '',
174
- ]"
175
171
  :style="cellStyleMap[TagType.TD].get(colKeyGen(col))"
172
+ :class="[col.className, fixedColClassMap.get(colKeyGen(col)), col.type === 'seq' ? 'seq-column' : '']"
176
173
  @click="e => onCellClick(e, row, col)"
174
+ @mouseenter="e => onCellMouseEnter(e, row, col)"
175
+ @mouseleave="e => onCellMouseLeave(e, row, col)"
176
+ @mouseover="e => onCellMouseOver(e, row, col)"
177
177
  >
178
178
  <component
179
179
  :is="col.customCell"
@@ -212,9 +212,9 @@
212
212
  * [] 计算的高亮颜色,挂在数据源上对象上,若多个表格使用同一个数据源对象会有问题。需要深拷贝。(解决方案:获取组件uid)
213
213
  * [] highlight-row 颜色不能恢复到active的颜色
214
214
  */
215
- import { CSSProperties, computed, onMounted, ref, shallowRef, toRaw, watch } from 'vue';
215
+ import { CSSProperties, computed, nextTick, onMounted, ref, shallowRef, toRaw, watch } from 'vue';
216
216
  import { DEFAULT_ROW_HEIGHT } from './const';
217
- import { HighlightConfig, Order, SeqConfig, SortConfig, SortOption, SortState, StkTableColumn, TagType, UniqKeyProp } from './types/index';
217
+ import { HighlightConfig, Order, SeqConfig, SortConfig, SortOption, SortState, StkTableColumn, TagType, UniqKey, UniqKeyProp } from './types/index';
218
218
  import { useAutoResize } from './useAutoResize';
219
219
  import { useColResize } from './useColResize';
220
220
  import { useFixedCol } from './useFixedCol';
@@ -223,7 +223,7 @@ import { useHighlight } from './useHighlight';
223
223
  import { useKeyboardArrowScroll } from './useKeyboardArrowScroll';
224
224
  import { useThDrag } from './useThDrag';
225
225
  import { useVirtualScroll } from './useVirtualScroll';
226
- import { createStkTableId, getCalculatedColWidth, getColWidth, transformWidthToStr, howDeepTheHeader, tableSort } from './utils';
226
+ import { createStkTableId, getCalculatedColWidth, getColWidth, howDeepTheHeader, tableSort, transformWidthToStr } from './utils';
227
227
 
228
228
  /** Generic stands for DataType */
229
229
  type DT = any;
@@ -277,6 +277,8 @@ const props = withDefaults(
277
277
  showOverflow?: boolean;
278
278
  /** 是否增加行hover class */
279
279
  showTrHoverClass?: boolean;
280
+ /** 是否高亮鼠标悬浮的单元格 */
281
+ cellHover?: boolean;
280
282
  /** 表头是否可拖动。支持回调函数。 */
281
283
  headerDrag?: boolean | ((col: StkTableColumn<DT>) => boolean);
282
284
  /**
@@ -318,6 +320,14 @@ const props = withDefaults(
318
320
  highlightConfig?: HighlightConfig;
319
321
  /** 序号列配置 */
320
322
  seqConfig?: SeqConfig;
323
+ /**
324
+ * 固定头,固定列实现方式。
325
+ *
326
+ * relative:固定列只能放在props.columns的两侧。如果列宽会变动则谨慎使用。
327
+ *
328
+ * 低版本浏览器只能为'relative',
329
+ */
330
+ cellFixedMode?: 'sticky' | 'relative';
321
331
  }>(),
322
332
  {
323
333
  width: '',
@@ -342,6 +352,7 @@ const props = withDefaults(
342
352
  showHeaderOverflow: false,
343
353
  showOverflow: false,
344
354
  showTrHoverClass: false,
355
+ cellHover: false,
345
356
  headerDrag: false,
346
357
  rowClassName: () => '',
347
358
  colResizable: false,
@@ -357,6 +368,7 @@ const props = withDefaults(
357
368
  hideHeaderTitle: false,
358
369
  highlightConfig: () => ({}),
359
370
  seqConfig: () => ({}),
371
+ cellFixedMode: 'sticky',
360
372
  },
361
373
  );
362
374
 
@@ -373,9 +385,9 @@ const emits = defineEmits<{
373
385
  (e: 'row-click', ev: MouseEvent, row: DT): void;
374
386
  /**
375
387
  * 选中一行触发。ev返回null表示不是点击事件触发的
376
- * ```(ev: MouseEvent | null, row: DT)```
388
+ * ```(ev: MouseEvent | null, row: DT, data: { select: boolean })```
377
389
  */
378
- (e: 'current-change', ev: MouseEvent | null, row: DT): void;
390
+ (e: 'current-change', ev: MouseEvent | null, row: DT, data: { select: boolean }): void;
379
391
  /**
380
392
  * 行双击事件
381
393
  * ```(ev: MouseEvent, row: DT)```
@@ -396,6 +408,21 @@ const emits = defineEmits<{
396
408
  * ```(ev: MouseEvent, row: DT, col: StkTableColumn<DT>)```
397
409
  */
398
410
  (e: 'cell-click', ev: MouseEvent, row: DT, col: StkTableColumn<DT>): void;
411
+ /**
412
+ * 单元格鼠标进入事件
413
+ * ```(ev: MouseEvent, row: DT, col: StkTableColumn<DT>)```
414
+ */
415
+ (e: 'cell-mouseenter', ev: MouseEvent, row: DT, col: StkTableColumn<DT>): void;
416
+ /**
417
+ * 单元格鼠标移出事件
418
+ * ```(ev: MouseEvent, row: DT, col: StkTableColumn<DT>)```
419
+ */
420
+ (e: 'cell-mouseleave', ev: MouseEvent, row: DT, col: StkTableColumn<DT>): void;
421
+ /**
422
+ * 单元格悬浮事件
423
+ * ```(ev: MouseEvent, row: DT, col: StkTableColumn<DT>)```
424
+ */
425
+ (e: 'cell-mouseover', ev: MouseEvent, row: DT, col: StkTableColumn<DT>): void;
399
426
  /**
400
427
  * 表头单元格点击事件
401
428
  * ```(ev: MouseEvent, col: StkTableColumn<DT>)```
@@ -441,14 +468,18 @@ const emits = defineEmits<{
441
468
  const tableContainerRef = ref<HTMLDivElement>();
442
469
  const colResizeIndicatorRef = ref<HTMLDivElement>();
443
470
  /** 当前选中的一行*/
444
- const currentItem = ref<DT | null>(null);
471
+ const currentRow = ref<DT | null>(null);
445
472
  /**
446
473
  * 保存当前选中行的key<br>
447
474
  * 原因:vue3 不用ref包dataSource时,row为原始对象,与currentItem(Ref)相比会不相等。
448
475
  */
449
- const currentItemKey = ref<any>(null);
450
- /** 当前hover的行 */
451
- const currentHover = ref<any | null>(null);
476
+ const currentRowKey = ref<any>(null);
477
+ /** 当前hover */
478
+ let currentHoverRow: DT = null;
479
+ /** 当前hover的行的key */
480
+ const currentHoverRowKey = ref(null);
481
+ /** 当前hover的列的key */
482
+ // const currentColHoverKey = ref(null);
452
483
 
453
484
  /** 排序的列dataIndex*/
454
485
  let sortCol = ref<string | null>();
@@ -474,6 +505,18 @@ const tableHeaderLast = shallowRef<StkTableColumn<DT>[]>([]);
474
505
 
475
506
  const dataSourceCopy = shallowRef<DT[]>([...props.dataSource]);
476
507
 
508
+ /**
509
+ * 列唯一键
510
+ * @param col
511
+ */
512
+ const colKeyGen = computed(() => {
513
+ if (typeof props.colKey === 'function') {
514
+ return (col: StkTableColumn<DT>) => (props.colKey as (col: StkTableColumn<DT>) => string)(col);
515
+ } else {
516
+ return (col: StkTableColumn<DT>) => (col as any)[props.colKey as string];
517
+ }
518
+ });
519
+
477
520
  /**高亮帧间隔
478
521
  const highlightStepDuration = Highlight_Color_Change_Freq / 1000 + 's';*/
479
522
 
@@ -557,16 +600,17 @@ watch(
557
600
  () => props.columns,
558
601
  () => {
559
602
  dealColumns();
560
- initVirtualScrollX();
603
+ nextTick(initVirtualScrollX);
561
604
  },
562
605
  );
563
606
  watch(
564
607
  () => props.virtualX,
565
- () => dealColumns(),
608
+ () => {
609
+ dealColumns();
610
+ nextTick(initVirtualScrollX);
611
+ },
566
612
  );
567
613
 
568
- dealColumns();
569
-
570
614
  watch(
571
615
  () => props.dataSource,
572
616
  val => {
@@ -596,6 +640,8 @@ watch(
596
640
 
597
641
  watch(() => props.fixedColShadow, dealFixedColShadow);
598
642
 
643
+ dealColumns();
644
+
599
645
  onMounted(() => {
600
646
  initVirtualScroll();
601
647
  updateFixedShadow();
@@ -695,21 +741,13 @@ function rowKeyGen(row: DT) {
695
741
  return key;
696
742
  }
697
743
 
698
- /**
699
- * 列唯一键
700
- * @param col
701
- */
702
- function colKeyGen(col: StkTableColumn<DT>) {
703
- return typeof props.colKey === 'function' ? props.colKey(col) : (col as any)[props.colKey];
704
- }
705
-
706
744
  /** 单元格样式 */
707
745
  const cellStyleMap = computed(() => {
708
746
  const thMap = new Map();
709
747
  const tdMap = new Map();
710
748
  tableHeaders.value.forEach((cols, depth) => {
711
749
  cols.forEach(col => {
712
- const colKey = colKeyGen(col);
750
+ const colKey = colKeyGen.value(col);
713
751
  const width = props.virtualX ? getCalculatedColWidth(col) + 'px' : transformWidthToStr(col.width);
714
752
  const style: CSSProperties = {
715
753
  width,
@@ -791,11 +829,16 @@ function onColumnSort(col?: StkTableColumn<DT>, click = true, options: { force?:
791
829
 
792
830
  function onRowClick(e: MouseEvent, row: DT) {
793
831
  emits('row-click', e, row);
794
- // 选中同一行不触发current-change 事件
795
- if (props.rowKey ? currentItemKey.value === rowKeyGen(row) : currentItem.value === row) return;
796
- currentItem.value = row;
797
- currentItemKey.value = rowKeyGen(row);
798
- emits('current-change', e, row);
832
+ // 选中同一行,取消当前选中行。
833
+ if (props.rowKey ? currentRowKey.value === rowKeyGen(row) : currentRow.value === row) {
834
+ currentRow.value = null;
835
+ currentRowKey.value = null;
836
+ emits('current-change', e, row, { select: false });
837
+ } else {
838
+ currentRow.value = row;
839
+ currentRowKey.value = rowKeyGen(row);
840
+ emits('current-change', e, row, { select: true });
841
+ }
799
842
  }
800
843
 
801
844
  function onRowDblclick(e: MouseEvent, row: DT) {
@@ -822,6 +865,23 @@ function onHeaderCellClick(e: MouseEvent, col: StkTableColumn<DT>) {
822
865
  emits('header-cell-click', e, col);
823
866
  }
824
867
 
868
+ /** td mouseenter */
869
+ function onCellMouseEnter(e: MouseEvent, row: DT, col: StkTableColumn<DT>) {
870
+ // currentColHoverKey.value = colKeyGen(col);
871
+ emits('cell-mouseenter', e, row, col);
872
+ }
873
+
874
+ /** td mouseleave */
875
+ function onCellMouseLeave(e: MouseEvent, row: DT, col: StkTableColumn<DT>) {
876
+ // currentColHoverKey.value = null;
877
+ emits('cell-mouseleave', e, row, col);
878
+ }
879
+
880
+ /** td mouseover event */
881
+ function onCellMouseOver(e: MouseEvent, row: DT, col: StkTableColumn<DT>) {
882
+ emits('cell-mouseover', e, row, col);
883
+ }
884
+
825
885
  /**
826
886
  * 鼠标滚轮事件监听
827
887
  * @param {MouseEvent} e
@@ -849,7 +909,7 @@ function onTableScroll(e: Event) {
849
909
  const isXScroll = scrollLeft !== vScrollLeft;
850
910
 
851
911
  // 纵向滚动有变化
852
- if (isYScroll && virtual_on.value) {
912
+ if (isYScroll) {
853
913
  updateVirtualScrollY(scrollTop);
854
914
  }
855
915
 
@@ -876,22 +936,22 @@ function onTableScroll(e: Event) {
876
936
 
877
937
  /** tr hover事件 */
878
938
  function onTrMouseOver(_e: MouseEvent, row: DT) {
879
- if (props.showTrHoverClass) {
880
- currentHover.value = rowKeyGen(row);
881
- }
939
+ if (currentHoverRow === row) return;
940
+ currentHoverRow = row;
941
+ currentHoverRowKey.value = rowKeyGen(row);
882
942
  }
883
943
 
884
944
  /**
885
945
  * 选中一行,
886
- * @param {string} rowKey
946
+ * @param {string} rowKey selected rowKey, null to unselect
887
947
  * @param {boolean} option.silent 是否触发回调
888
948
  */
889
949
  function setCurrentRow(rowKey: string, option = { silent: false }) {
890
950
  if (!dataSourceCopy.value.length) return;
891
- currentItem.value = dataSourceCopy.value.find(it => rowKeyGen(it) === rowKey);
892
- currentItemKey.value = rowKeyGen(currentItem.value);
951
+ currentRow.value = dataSourceCopy.value.find(it => rowKeyGen(it) === rowKey);
952
+ currentRowKey.value = rowKeyGen(currentRow.value);
893
953
  if (!option.silent) {
894
- emits('current-change', null, currentItem.value);
954
+ emits('current-change', /** no Event */ null, currentRow.value, { select: Boolean(currentRowKey.value) });
895
955
  }
896
956
  }
897
957