xt-element-ui 1.2.1 → 1.2.2
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/index.common.js +197 -346
- package/lib/index.css +1 -1
- package/lib/index.umd.js +197 -346
- package/lib/index.umd.min.js +4 -4
- package/package.json +3 -4
- package/src/components/ex-button/index.vue +7 -1
- package/src/components/ex-button/style/index.scss +32 -2
- package/src/components/ex-card/index.vue +0 -82
- package/src/components/ex-card/style/index.scss +7 -3
- package/src/components/ex-table/index.vue +107 -275
- package/src/components/ex-table/virtualScrollData.js +35 -0
- package/src/components/xt-config-provider/index.vue +10 -10
- package/src/components/xt-text/style/index.scss +4 -4
- package/src/index.js +4 -1
- package/src/styles/css-variables.scss +0 -1
- package/src/styles/element-theme.scss +11 -3
|
@@ -8,32 +8,40 @@
|
|
|
8
8
|
</div>
|
|
9
9
|
</div>
|
|
10
10
|
|
|
11
|
-
<!--
|
|
11
|
+
<!-- 虚拟滚动固定表头:复用 el-table 列布局,与 body 表头对齐 -->
|
|
12
12
|
<div
|
|
13
|
-
v-if="virtualScroll &&
|
|
13
|
+
v-if="virtualScroll && computedHeight"
|
|
14
14
|
ref="fixedHeader"
|
|
15
15
|
class="ex-table-fixed-header"
|
|
16
|
-
:style="{ marginLeft: -scrollLeft + 'px' }"
|
|
17
16
|
>
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
17
|
+
<el-table
|
|
18
|
+
ref="headerTable"
|
|
19
|
+
:data="headerTableData"
|
|
20
|
+
class="ex-table ex-table-header-only"
|
|
21
|
+
>
|
|
22
|
+
<el-table-column v-if="selection" type="selection" width="55" :fixed="selectionFixed" />
|
|
23
|
+
<el-table-column
|
|
24
|
+
v-if="showIndex"
|
|
25
|
+
type="index"
|
|
26
|
+
width="60"
|
|
27
|
+
label="#"
|
|
28
|
+
:fixed="indexFixed"
|
|
29
|
+
/>
|
|
30
|
+
<template v-for="col in flattenedColumns">
|
|
31
|
+
<el-table-column
|
|
32
|
+
v-if="col.children && col.children.length"
|
|
33
|
+
:key="col._key"
|
|
34
|
+
v-bind="getColumnProps(col)"
|
|
35
|
+
>
|
|
36
|
+
<el-table-column
|
|
37
|
+
v-for="child in col.children"
|
|
38
|
+
:key="child._key || child.prop"
|
|
39
|
+
v-bind="getColumnProps(child)"
|
|
40
|
+
/>
|
|
41
|
+
</el-table-column>
|
|
42
|
+
<el-table-column v-else :key="col._key" v-bind="getColumnProps(col)" />
|
|
43
|
+
</template>
|
|
44
|
+
</el-table>
|
|
37
45
|
</div>
|
|
38
46
|
|
|
39
47
|
<!-- 表格主体 -->
|
|
@@ -106,6 +114,7 @@
|
|
|
106
114
|
ref="table"
|
|
107
115
|
:data="visibleData"
|
|
108
116
|
:height="computedHeight"
|
|
117
|
+
:max-height="computedMaxHeight"
|
|
109
118
|
:span-method="groupColumns.length ? handleSpanMethod : undefined"
|
|
110
119
|
:row-class-name="getRowClassName"
|
|
111
120
|
v-bind="$attrs"
|
|
@@ -189,6 +198,8 @@ export default {
|
|
|
189
198
|
title: { type: String, default: '' },
|
|
190
199
|
// 高度
|
|
191
200
|
height: { type: [Number, String], default: null },
|
|
201
|
+
// 最大高度(非虚拟滚动时与 height 二选一,均支持固定表头)
|
|
202
|
+
maxHeight: { type: [Number, String], default: null },
|
|
192
203
|
// 虚拟滚动
|
|
193
204
|
virtualScroll: { type: Boolean, default: false },
|
|
194
205
|
// 预估行高
|
|
@@ -226,8 +237,6 @@ export default {
|
|
|
226
237
|
visibleStartIndex: 0,
|
|
227
238
|
visibleEndIndex: 0,
|
|
228
239
|
visibleCount: 0,
|
|
229
|
-
// 表格宽度(用于自适应列宽计算)
|
|
230
|
-
tableWidth: 0,
|
|
231
240
|
// 分组合并缓存
|
|
232
241
|
spanCache: {},
|
|
233
242
|
// 列扁平化缓存
|
|
@@ -244,203 +253,19 @@ export default {
|
|
|
244
253
|
|
|
245
254
|
computedHeight() {
|
|
246
255
|
if (this.virtualScroll) {
|
|
247
|
-
return this.height || 400
|
|
256
|
+
return this.height || this.maxHeight || 400
|
|
248
257
|
}
|
|
249
258
|
return this.height || undefined
|
|
250
259
|
},
|
|
251
260
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
// 选择列
|
|
256
|
-
if (this.selection) width += 55
|
|
257
|
-
// 序号列
|
|
258
|
-
if (this.showIndex) width += 60
|
|
259
|
-
// fixed 列
|
|
260
|
-
const sumFixedWidth = (cols) => {
|
|
261
|
-
cols.forEach(c => {
|
|
262
|
-
if (c.fixed && (c.width || c.minWidth)) {
|
|
263
|
-
width += typeof c.width === 'number' ? c.width : (typeof c.minWidth === 'number' ? c.minWidth : 100)
|
|
264
|
-
}
|
|
265
|
-
if (c.children && c.children.length) sumFixedWidth(c.children)
|
|
266
|
-
})
|
|
267
|
-
}
|
|
268
|
-
sumFixedWidth(this.columns)
|
|
269
|
-
return width
|
|
261
|
+
computedMaxHeight() {
|
|
262
|
+
if (this.virtualScroll || this.height) return undefined
|
|
263
|
+
return this.maxHeight || undefined
|
|
270
264
|
},
|
|
271
265
|
|
|
272
|
-
//
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
const sumWidth = (cols) => {
|
|
276
|
-
cols.forEach(c => {
|
|
277
|
-
if (!c.fixed && c.width) {
|
|
278
|
-
width += typeof c.width === 'number' ? c.width : parseInt(c.width) || 0
|
|
279
|
-
}
|
|
280
|
-
if (c.children && c.children.length) sumWidth(c.children)
|
|
281
|
-
})
|
|
282
|
-
}
|
|
283
|
-
sumWidth(this.columns)
|
|
284
|
-
return width
|
|
285
|
-
},
|
|
286
|
-
|
|
287
|
-
// 计算需要自适应的列数(非固定列且未设置width)
|
|
288
|
-
autoColumnCount() {
|
|
289
|
-
let count = 0
|
|
290
|
-
const countCols = (cols) => {
|
|
291
|
-
cols.forEach(c => {
|
|
292
|
-
if (!c.fixed) {
|
|
293
|
-
if (c.children && c.children.length) {
|
|
294
|
-
countCols(c.children)
|
|
295
|
-
} else if (!c.width) {
|
|
296
|
-
// 只有未设置width的非固定列才参与自适应
|
|
297
|
-
count++
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
})
|
|
301
|
-
}
|
|
302
|
-
countCols(this.columns)
|
|
303
|
-
return count
|
|
304
|
-
},
|
|
305
|
-
|
|
306
|
-
// 自适应列宽(未设置width的非固定列均分剩余宽度)
|
|
307
|
-
autoColumnWidth() {
|
|
308
|
-
const totalWidth = this.tableWidth || 1000
|
|
309
|
-
const gutter = 12 // el-table 默认 gutter
|
|
310
|
-
const fixedWidth = this.fixedColumnWidth
|
|
311
|
-
const nonFixedWithWidth = this.nonFixedColumnWidthWithWidth
|
|
312
|
-
const autoCount = this.autoColumnCount
|
|
313
|
-
|
|
314
|
-
if (autoCount <= 0) return 100 // 默认宽度
|
|
315
|
-
|
|
316
|
-
// 自适应宽度 = (总宽度 - gutter - 固定列宽度 - 非固定列中已设置的width)/ 需要自适应的列数
|
|
317
|
-
const availableWidth = totalWidth - gutter - fixedWidth - nonFixedWithWidth
|
|
318
|
-
return Math.max(80, Math.floor(availableWidth / autoCount)) // 最小80px
|
|
319
|
-
},
|
|
320
|
-
|
|
321
|
-
// 表头列定义(用于 colgroup,与 headerRows 列数保持一致)
|
|
322
|
-
headerCols() {
|
|
323
|
-
const cols = []
|
|
324
|
-
|
|
325
|
-
// 选择列
|
|
326
|
-
if (this.selection) {
|
|
327
|
-
cols.push({ _key: 'prepend_selection', _width: 55, _minWidth: 55 })
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
// 序号列
|
|
331
|
-
if (this.showIndex) {
|
|
332
|
-
cols.push({ _key: 'prepend_index', _width: 60, _minWidth: 60 })
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
// 数据列(只取叶子节点,使用一致的key生成)
|
|
336
|
-
const addLeafCols = (columns, parentPath = '') => {
|
|
337
|
-
columns.forEach((col, index) => {
|
|
338
|
-
const path = parentPath ? `${parentPath}_${index}` : String(index)
|
|
339
|
-
const key = this.generateColKey(col, path)
|
|
340
|
-
|
|
341
|
-
if (col.children && col.children.length) {
|
|
342
|
-
addLeafCols(col.children, path)
|
|
343
|
-
} else {
|
|
344
|
-
cols.push({
|
|
345
|
-
_key: key,
|
|
346
|
-
_width: this.getColumnWidth(col),
|
|
347
|
-
_minWidth: col.minWidth
|
|
348
|
-
})
|
|
349
|
-
}
|
|
350
|
-
})
|
|
351
|
-
}
|
|
352
|
-
addLeafCols(this.columns)
|
|
353
|
-
|
|
354
|
-
return cols
|
|
355
|
-
},
|
|
356
|
-
|
|
357
|
-
// 表头层级结构(用于自定义固定表头渲染)
|
|
358
|
-
headerRows() {
|
|
359
|
-
const rows = []
|
|
360
|
-
let maxDepth = 1
|
|
361
|
-
|
|
362
|
-
// 计算最大深度
|
|
363
|
-
const calcDepth = (cols, depth) => {
|
|
364
|
-
maxDepth = Math.max(maxDepth, depth)
|
|
365
|
-
cols.forEach(c => { if (c.children && c.children.length) calcDepth(c.children, depth + 1) })
|
|
366
|
-
}
|
|
367
|
-
if (this.columns.length) calcDepth(this.columns, 1)
|
|
368
|
-
|
|
369
|
-
// 初始化行
|
|
370
|
-
for (let i = 0; i < maxDepth; i++) rows.push([])
|
|
371
|
-
|
|
372
|
-
// 计算叶子数量
|
|
373
|
-
const countLeaves = (cols) => {
|
|
374
|
-
let n = 0
|
|
375
|
-
cols.forEach(c => {
|
|
376
|
-
if (c.children && c.children.length) n += countLeaves(c.children)
|
|
377
|
-
else n++
|
|
378
|
-
})
|
|
379
|
-
return n
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
// 选择列 / 序号列占位(仅第一行,rowspan 跨所有行)
|
|
383
|
-
if (this.selection) {
|
|
384
|
-
rows[0].push({
|
|
385
|
-
_key: 'prepend_selection',
|
|
386
|
-
_rowspan: maxDepth,
|
|
387
|
-
_colspan: 1,
|
|
388
|
-
_style: { width: '55px' },
|
|
389
|
-
_hidden: false,
|
|
390
|
-
label: ''
|
|
391
|
-
})
|
|
392
|
-
for (let i = 1; i < maxDepth; i++) {
|
|
393
|
-
rows[i].push({ _key: 'prepend_selection_' + i, _rowspan: 0, _colspan: 1, _hidden: true, label: '' })
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
if (this.showIndex) {
|
|
397
|
-
rows[0].push({
|
|
398
|
-
_key: 'prepend_index',
|
|
399
|
-
_rowspan: maxDepth,
|
|
400
|
-
_colspan: 1,
|
|
401
|
-
_style: { width: '60px' },
|
|
402
|
-
_hidden: false,
|
|
403
|
-
label: '#'
|
|
404
|
-
})
|
|
405
|
-
for (let i = 1; i < maxDepth; i++) {
|
|
406
|
-
rows[i].push({ _key: 'prepend_index_' + i, _rowspan: 0, _colspan: 1, _hidden: true, label: '' })
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
// 填充列
|
|
411
|
-
if (this.columns.length) {
|
|
412
|
-
const fill = (cols, depth, parentPath = '') => {
|
|
413
|
-
cols.forEach((c, index) => {
|
|
414
|
-
const path = parentPath ? `${parentPath}_${index}` : String(index)
|
|
415
|
-
const key = this.generateColKey(c, path)
|
|
416
|
-
const hasKids = c.children && c.children.length
|
|
417
|
-
const style = {}
|
|
418
|
-
|
|
419
|
-
// 如果有固定宽度,使用固定宽度;否则使用自适应宽度
|
|
420
|
-
if (c.width) {
|
|
421
|
-
style.width = typeof c.width === 'number' ? c.width + 'px' : c.width
|
|
422
|
-
} else if (!c.fixed && this.virtualScroll) {
|
|
423
|
-
// 非固定列且虚拟滚动时使用自适应宽度
|
|
424
|
-
style.width = this.autoColumnWidth + 'px'
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
if (c.minWidth) style.minWidth = typeof c.minWidth === 'number' ? c.minWidth + 'px' : c.minWidth
|
|
428
|
-
|
|
429
|
-
rows[depth].push({
|
|
430
|
-
_key: key,
|
|
431
|
-
_rowspan: hasKids ? 1 : maxDepth - depth,
|
|
432
|
-
_colspan: hasKids ? countLeaves(c.children) : 1,
|
|
433
|
-
_style: style,
|
|
434
|
-
_hidden: !c.label && !c.prop,
|
|
435
|
-
label: c.label || ''
|
|
436
|
-
})
|
|
437
|
-
if (hasKids) fill(c.children, depth + 1, path)
|
|
438
|
-
})
|
|
439
|
-
}
|
|
440
|
-
fill(this.columns, 0)
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
return rows
|
|
266
|
+
// 虚拟滚动固定表头占位数据(仅渲染表头,不渲染 body 行)
|
|
267
|
+
headerTableData() {
|
|
268
|
+
return []
|
|
444
269
|
},
|
|
445
270
|
|
|
446
271
|
// 处理后的数据(注入小计/总计行)
|
|
@@ -493,22 +318,25 @@ export default {
|
|
|
493
318
|
return start * this.rowHeight
|
|
494
319
|
},
|
|
495
320
|
|
|
496
|
-
//
|
|
321
|
+
// 扁平化列配置(为每级列补充 _key)
|
|
497
322
|
flattenedColumns() {
|
|
498
323
|
if (this.flattenedColumnsCache.length) return this.flattenedColumnsCache
|
|
499
|
-
const
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
const key = col.prop || col.label ||
|
|
503
|
-
|
|
324
|
+
const assignKeys = (cols, parentPath = '') => {
|
|
325
|
+
return cols.map((col, index) => {
|
|
326
|
+
const path = parentPath ? `${parentPath}_${index}` : String(index)
|
|
327
|
+
const key = col.prop || col.slot || col.label || path
|
|
328
|
+
const item = { ...col, _key: key }
|
|
329
|
+
if (col.children && col.children.length) {
|
|
330
|
+
item.children = assignKeys(col.children, path)
|
|
331
|
+
}
|
|
332
|
+
return item
|
|
504
333
|
})
|
|
505
334
|
}
|
|
506
|
-
|
|
507
|
-
this.flattenedColumnsCache
|
|
508
|
-
return result
|
|
335
|
+
this.flattenedColumnsCache = assignKeys(this.columns)
|
|
336
|
+
return this.flattenedColumnsCache
|
|
509
337
|
},
|
|
510
338
|
|
|
511
|
-
//
|
|
339
|
+
// 虚拟滚动时的可见数据(附带 _realIndex 供序号列使用)
|
|
512
340
|
visibleData() {
|
|
513
341
|
const data = this.processedTableData
|
|
514
342
|
if (!this.virtualScroll || data.length === 0) {
|
|
@@ -516,7 +344,10 @@ export default {
|
|
|
516
344
|
}
|
|
517
345
|
const start = Math.max(0, this.visibleStartIndex - this.bufferSize)
|
|
518
346
|
const end = Math.min(data.length, this.visibleEndIndex + this.bufferSize)
|
|
519
|
-
return data.slice(start, end)
|
|
347
|
+
return data.slice(start, end).map((row, i) => ({
|
|
348
|
+
...row,
|
|
349
|
+
_realIndex: start + i
|
|
350
|
+
}))
|
|
520
351
|
}
|
|
521
352
|
},
|
|
522
353
|
|
|
@@ -529,6 +360,7 @@ export default {
|
|
|
529
360
|
this.$nextTick(() => {
|
|
530
361
|
this.measureRowHeight()
|
|
531
362
|
this.updateVisibleRange()
|
|
363
|
+
this.syncTableLayout()
|
|
532
364
|
})
|
|
533
365
|
}
|
|
534
366
|
},
|
|
@@ -538,10 +370,25 @@ export default {
|
|
|
538
370
|
columns: {
|
|
539
371
|
handler() {
|
|
540
372
|
this.flattenedColumnsCache = []
|
|
373
|
+
if (this.virtualScroll) {
|
|
374
|
+
this.$nextTick(() => this.syncTableLayout())
|
|
375
|
+
}
|
|
541
376
|
},
|
|
542
377
|
deep: true
|
|
543
378
|
},
|
|
544
379
|
|
|
380
|
+
height() {
|
|
381
|
+
if (this.virtualScroll) {
|
|
382
|
+
this.$nextTick(() => this.syncTableLayout())
|
|
383
|
+
}
|
|
384
|
+
},
|
|
385
|
+
|
|
386
|
+
maxHeight() {
|
|
387
|
+
if (this.virtualScroll) {
|
|
388
|
+
this.$nextTick(() => this.syncTableLayout())
|
|
389
|
+
}
|
|
390
|
+
},
|
|
391
|
+
|
|
545
392
|
virtualScroll(val) {
|
|
546
393
|
if (val) {
|
|
547
394
|
this.$nextTick(() => this.initVirtualScroll())
|
|
@@ -558,7 +405,7 @@ export default {
|
|
|
558
405
|
// 监听窗口resize,更新表格宽度
|
|
559
406
|
this.resizeHandler = () => {
|
|
560
407
|
if (this.virtualScroll) {
|
|
561
|
-
this.$nextTick(() => this.
|
|
408
|
+
this.$nextTick(() => this.syncTableLayout())
|
|
562
409
|
}
|
|
563
410
|
}
|
|
564
411
|
window.addEventListener('resize', this.resizeHandler)
|
|
@@ -797,41 +644,35 @@ export default {
|
|
|
797
644
|
},
|
|
798
645
|
|
|
799
646
|
doLayout() {
|
|
800
|
-
this
|
|
647
|
+
this.syncTableLayout()
|
|
801
648
|
},
|
|
802
649
|
|
|
803
|
-
//
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
if (!col.fixed && this.virtualScroll) {
|
|
811
|
-
return this.autoColumnWidth
|
|
812
|
-
}
|
|
813
|
-
// 默认宽度
|
|
814
|
-
if (col.minWidth) {
|
|
815
|
-
return typeof col.minWidth === 'number' ? col.minWidth : col.minWidth.replace('px', '')
|
|
816
|
-
}
|
|
817
|
-
return 100
|
|
650
|
+
// ==================== 虚拟滚动固定表头 ====================
|
|
651
|
+
syncTableLayout() {
|
|
652
|
+
const bodyTable = this.$refs.table
|
|
653
|
+
const headerTable = this.$refs.headerTable
|
|
654
|
+
if (bodyTable) bodyTable.doLayout()
|
|
655
|
+
if (headerTable) headerTable.doLayout()
|
|
656
|
+
this.syncHeaderScroll(this.scrollLeft)
|
|
818
657
|
},
|
|
819
658
|
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
659
|
+
syncHeaderScroll(scrollLeft) {
|
|
660
|
+
const headerTable = this.$refs.headerTable
|
|
661
|
+
if (!headerTable) return
|
|
662
|
+
const headerWrapper = headerTable.$el.querySelector('.el-table__header-wrapper')
|
|
663
|
+
if (headerWrapper) {
|
|
664
|
+
headerWrapper.scrollLeft = scrollLeft
|
|
825
665
|
}
|
|
826
666
|
},
|
|
827
667
|
|
|
828
668
|
// ==================== 虚拟滚动 ====================
|
|
829
669
|
initVirtualScroll() {
|
|
830
|
-
this.
|
|
670
|
+
this.rowHeight = this.rowInitHeight
|
|
831
671
|
this.measureRowHeight()
|
|
832
672
|
if (this.processedTableData.length > 0) {
|
|
833
673
|
this.updateVisibleRange()
|
|
834
674
|
}
|
|
675
|
+
this.syncTableLayout()
|
|
835
676
|
},
|
|
836
677
|
|
|
837
678
|
measureRowHeight() {
|
|
@@ -849,6 +690,7 @@ export default {
|
|
|
849
690
|
if (this.virtualScroll) {
|
|
850
691
|
this.scrollTop = target.scrollTop
|
|
851
692
|
this.updateVisibleRange()
|
|
693
|
+
this.syncHeaderScroll(target.scrollLeft)
|
|
852
694
|
}
|
|
853
695
|
},
|
|
854
696
|
|
|
@@ -947,8 +789,12 @@ export default {
|
|
|
947
789
|
|
|
948
790
|
/* 虚拟滚动容器 */
|
|
949
791
|
.ex-table-virtual {
|
|
950
|
-
overflow:
|
|
792
|
+
overflow: overlay;
|
|
951
793
|
position: relative;
|
|
794
|
+
/* Firefox 隐藏滚动条 */
|
|
795
|
+
scrollbar-width: none;
|
|
796
|
+
/* IE/旧 Edge 隐藏滚动条 */
|
|
797
|
+
-ms-overflow-style: none;
|
|
952
798
|
}
|
|
953
799
|
|
|
954
800
|
.ex-table-virtual-inner {
|
|
@@ -966,39 +812,25 @@ export default {
|
|
|
966
812
|
padding: 16px 0;
|
|
967
813
|
}
|
|
968
814
|
|
|
969
|
-
/*
|
|
815
|
+
/* 虚拟滚动固定表头(header-only el-table) */
|
|
970
816
|
.ex-table-fixed-header {
|
|
971
817
|
overflow: hidden;
|
|
972
|
-
|
|
973
|
-
background: #fafafa;
|
|
818
|
+
flex-shrink: 0;
|
|
974
819
|
}
|
|
975
820
|
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
821
|
+
/* 虚拟滚动表头强制补上 gutter 占位 */
|
|
822
|
+
.ex-table-fixed-header >>> .el-table__header-wrapper thead tr .el-table__cell.gutter {
|
|
823
|
+
display: table-cell;
|
|
824
|
+
width: 8px; /* 和滚动条宽度一致 */
|
|
980
825
|
}
|
|
981
826
|
|
|
982
|
-
.ex-table-fixed-header-table th {
|
|
983
|
-
padding: 12px 8px;
|
|
984
|
-
text-align: left;
|
|
985
|
-
font-weight: 500;
|
|
986
|
-
font-size: 14px;
|
|
987
|
-
color: #606266;
|
|
988
|
-
border-bottom: 1px solid #ebeef5;
|
|
989
|
-
border-right: 1px solid #ebeef5;
|
|
990
|
-
white-space: nowrap;
|
|
991
|
-
overflow: hidden;
|
|
992
|
-
text-overflow: ellipsis;
|
|
993
|
-
background: #fafafa;
|
|
994
|
-
box-sizing: border-box;
|
|
995
|
-
}
|
|
996
827
|
|
|
997
|
-
.ex-table-
|
|
998
|
-
|
|
828
|
+
.ex-table-header-only >>> .el-table__body-wrapper,
|
|
829
|
+
.ex-table-header-only >>> .el-table__empty-block {
|
|
830
|
+
display: none;
|
|
999
831
|
}
|
|
1000
832
|
|
|
1001
|
-
.ex-table-
|
|
1002
|
-
|
|
833
|
+
.ex-table-header-only >>> .el-table__header-wrapper {
|
|
834
|
+
overflow: hidden;
|
|
1003
835
|
}
|
|
1004
836
|
</style>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 生成虚拟滚动演示数据
|
|
3
|
+
* @param {number} count 数据条数,默认 10000
|
|
4
|
+
* @returns {Array}
|
|
5
|
+
*/
|
|
6
|
+
export function createVirtualScrollData(count = 10000) {
|
|
7
|
+
const departments = ['研发部', '产品部', '运营部', '财务部', '市场部']
|
|
8
|
+
const positions = ['工程师', '产品经理', '运营专员', '财务主管', '市场经理']
|
|
9
|
+
const statuses = ['在职', '休假', '离职']
|
|
10
|
+
|
|
11
|
+
return Array.from({ length: count }, (_, i) => ({
|
|
12
|
+
id: i + 1,
|
|
13
|
+
name: `用户${i + 1}`,
|
|
14
|
+
department: departments[i % departments.length],
|
|
15
|
+
position: positions[i % positions.length],
|
|
16
|
+
email: `user${i + 1}@example.com`,
|
|
17
|
+
phone: `13800138${String(i).padStart(4, '0')}`,
|
|
18
|
+
address: `北京市朝阳区第${i + 1}号街道`,
|
|
19
|
+
salary: 5000 + Math.floor(Math.random() * 10000),
|
|
20
|
+
status: statuses[i % statuses.length]
|
|
21
|
+
}))
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** 虚拟滚动演示列配置 */
|
|
25
|
+
export const virtualScrollColumns = [
|
|
26
|
+
{ prop: 'id', label: 'ID', fixed: 'left', width: 80 },
|
|
27
|
+
{ prop: 'name', label: '姓名', fixed: 'left', width: 120 },
|
|
28
|
+
{ prop: 'department', label: '部门', width: 150 },
|
|
29
|
+
{ prop: 'position', label: '职位', width: 150 },
|
|
30
|
+
{ prop: 'email', label: '邮箱', width: 200 },
|
|
31
|
+
{ prop: 'phone', label: '电话', width: 130 },
|
|
32
|
+
{ prop: 'address', label: '地址', width: 200 },
|
|
33
|
+
{ prop: 'salary', label: '薪资', width: 120 },
|
|
34
|
+
{ prop: 'status', label: '状态', fixed: 'right', width: 100 }
|
|
35
|
+
]
|
|
@@ -13,25 +13,25 @@ export default {
|
|
|
13
13
|
},
|
|
14
14
|
watch: {
|
|
15
15
|
theme(newVal) {
|
|
16
|
-
this
|
|
16
|
+
this.xtConfig ={
|
|
17
17
|
theme: newVal,
|
|
18
18
|
size: this.size,
|
|
19
19
|
primaryColor: this.primaryColor
|
|
20
|
-
}
|
|
20
|
+
}
|
|
21
21
|
},
|
|
22
22
|
size(newVal) {
|
|
23
|
-
this
|
|
24
|
-
theme:
|
|
25
|
-
size:
|
|
23
|
+
this.xtConfig ={
|
|
24
|
+
theme: newVal,
|
|
25
|
+
size: this.size,
|
|
26
26
|
primaryColor: this.primaryColor
|
|
27
|
-
}
|
|
27
|
+
}
|
|
28
28
|
},
|
|
29
29
|
primaryColor(newVal) {
|
|
30
|
-
this
|
|
31
|
-
theme:
|
|
30
|
+
this.xtConfig ={
|
|
31
|
+
theme: newVal,
|
|
32
32
|
size: this.size,
|
|
33
|
-
primaryColor:
|
|
34
|
-
}
|
|
33
|
+
primaryColor: this.primaryColor
|
|
34
|
+
}
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
37
|
render(h) {
|
|
@@ -76,17 +76,17 @@
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
// 暗色主题
|
|
79
|
-
|
|
79
|
+
[data-theme='dark'] .xt-text--primary {
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
[data-theme='dark'] .xt-text--success {
|
|
83
83
|
color: $xt-dark-color-success;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
[data-theme='dark'] .xt-text--warning {
|
|
87
87
|
color: $xt-dark-color-warning;
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
[data-theme='dark'] .xt-text--danger {
|
|
91
91
|
color: $xt-dark-color-danger;
|
|
92
92
|
}
|
package/src/index.js
CHANGED
|
@@ -96,6 +96,7 @@ const install = function (Vue, options = {}) {
|
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
if (process.env.NODE_ENV === 'development') {
|
|
99
100
|
// 导入内部 element-ui 依赖(作为内部依赖,不与外部冲突)
|
|
100
101
|
const ElementUI = require('element-ui')
|
|
101
102
|
|
|
@@ -104,7 +105,6 @@ const install = function (Vue, options = {}) {
|
|
|
104
105
|
// ex-table 等组件内部会直接使用 element-ui 的组件
|
|
105
106
|
|
|
106
107
|
// 在开发环境下注册 ElementUI 组件为 Ex 开头(方便文档和示例使用)
|
|
107
|
-
if (process.env.NODE_ENV === 'development') {
|
|
108
108
|
registerElementExComponents(Vue, ElementUI)
|
|
109
109
|
}
|
|
110
110
|
|
|
@@ -140,6 +140,9 @@ export default {
|
|
|
140
140
|
// ExChart 组件按需导出(使用时需自行安装 echarts 依赖)
|
|
141
141
|
export { default as ExChart } from './components/ex-chart'
|
|
142
142
|
|
|
143
|
+
// ExTable 虚拟滚动演示数据工具
|
|
144
|
+
export { createVirtualScrollData, virtualScrollColumns } from './components/ex-table/virtualScrollData'
|
|
145
|
+
|
|
143
146
|
// 导出工具函数和变量
|
|
144
147
|
export {
|
|
145
148
|
utils,
|