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/README.md +32 -3
- package/lib/src/StkTable/StkTable.vue.d.ts +42 -6
- package/lib/src/StkTable/useColResize.d.ts +3 -3
- package/lib/src/StkTable/useFixedCol.d.ts +4 -4
- package/lib/src/StkTable/useVirtualScroll.d.ts +4 -1
- package/lib/stk-table-vue.js +117 -76
- package/lib/style.css +116 -123
- package/package.json +1 -1
- package/src/StkTable/StkTable.vue +106 -46
- package/src/StkTable/style.less +205 -229
- package/src/StkTable/useColResize.ts +5 -5
- package/src/StkTable/useFixedCol.ts +4 -4
- package/src/StkTable/useFixedStyle.ts +30 -9
- package/src/StkTable/useHighlight.ts +5 -4
- package/src/StkTable/useVirtualScroll.ts +19 -15
- package/src/StkTable/utils.ts +1 -1
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 .
|
|
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 .
|
|
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 .
|
|
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 .
|
|
225
|
+
.stk-table .fixed-cell--left{
|
|
165
226
|
--shadow-rotate:90deg;
|
|
166
227
|
}
|
|
167
|
-
.stk-table .
|
|
228
|
+
.stk-table .fixed-cell--left.fixed-cell--shadow::after{
|
|
168
229
|
right:-10px;
|
|
169
230
|
}
|
|
170
|
-
.stk-table .
|
|
231
|
+
.stk-table .fixed-cell--right{
|
|
171
232
|
--shadow-rotate:-90deg;
|
|
172
233
|
}
|
|
173
|
-
.stk-table .
|
|
234
|
+
.stk-table .fixed-cell--right.fixed-cell--shadow::after{
|
|
174
235
|
left:-10px;
|
|
175
236
|
}
|
|
176
|
-
.stk-table .
|
|
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 .
|
|
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 .
|
|
251
|
+
.stk-table .table-header-title{
|
|
224
252
|
overflow:hidden;
|
|
225
253
|
align-self:flex-start;
|
|
226
254
|
}
|
|
227
|
-
.stk-table .
|
|
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 .
|
|
235
|
-
.stk-table .
|
|
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 .
|
|
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 .
|
|
273
|
+
.stk-table .table-header-resizer.left{
|
|
246
274
|
left:0;
|
|
247
275
|
}
|
|
248
|
-
.stk-table .
|
|
276
|
+
.stk-table .table-header-resizer.right{
|
|
249
277
|
right:0;
|
|
250
278
|
}
|
|
251
|
-
.stk-table .
|
|
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
|
@@ -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"
|
|
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(
|
|
155
|
-
hover: rowKey ? rowKeyGen(row) ===
|
|
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"
|
|
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,
|
|
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
|
|
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
|
|
450
|
-
/** 当前hover
|
|
451
|
-
|
|
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
|
-
() =>
|
|
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
|
-
//
|
|
795
|
-
if (props.rowKey ?
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
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
|
|
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 (
|
|
880
|
-
|
|
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
|
-
|
|
892
|
-
|
|
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,
|
|
954
|
+
emits('current-change', /** no Event */ null, currentRow.value, { select: Boolean(currentRowKey.value) });
|
|
895
955
|
}
|
|
896
956
|
}
|
|
897
957
|
|