evui 3.3.8 → 3.3.11
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/dist/evui.common.js +2982 -792
- package/dist/evui.common.js.map +1 -1
- package/dist/evui.umd.js +2982 -792
- package/dist/evui.umd.js.map +1 -1
- package/dist/evui.umd.min.js +1 -1
- package/dist/evui.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/src/components/chart/Chart.vue +15 -6
- package/src/components/chart/chart.core.js +86 -31
- package/src/components/chart/element/element.bar.js +9 -3
- package/src/components/chart/element/element.heatmap.js +213 -0
- package/src/components/chart/element/element.pie.js +75 -5
- package/src/components/chart/element/element.scatter.js +26 -9
- package/src/components/chart/element/element.tip.js +158 -13
- package/src/components/chart/helpers/helpers.constant.js +22 -0
- package/src/components/chart/model/model.series.js +4 -0
- package/src/components/chart/model/model.store.js +166 -2
- package/src/components/chart/plugins/plugins.interaction.js +78 -10
- package/src/components/chart/plugins/plugins.legend.js +213 -42
- package/src/components/chart/plugins/plugins.pie.js +2 -0
- package/src/components/chart/plugins/plugins.tooltip.js +249 -6
- package/src/components/chart/scale/scale.js +20 -2
- package/src/components/chart/scale/scale.step.js +20 -5
- package/src/components/chart/scale/scale.time.category.js +20 -2
- package/src/components/chart/uses.js +20 -3
- package/src/components/grid/Grid.vue +276 -132
- package/src/components/grid/grid.filter.window.vue +1 -0
- package/src/components/grid/grid.pagination.vue +75 -0
- package/src/components/grid/grid.summary.vue +221 -0
- package/src/components/grid/style/grid.scss +0 -14
- package/src/components/grid/uses.js +157 -78
- package/src/components/pagination/Pagination.vue +20 -17
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { getCurrentInstance, nextTick } from 'vue';
|
|
2
|
-
import {
|
|
2
|
+
import { uniqBy } from 'lodash-es';
|
|
3
3
|
import { numberWithComma } from '@/common/utils';
|
|
4
4
|
|
|
5
5
|
const ROW_INDEX = 0;
|
|
6
6
|
const ROW_CHECK_INDEX = 1;
|
|
7
7
|
const ROW_DATA_INDEX = 2;
|
|
8
|
+
const ROW_SELECT_INDEX = 3;
|
|
8
9
|
|
|
9
10
|
export const commonFunctions = () => {
|
|
10
11
|
const { props } = getCurrentInstance();
|
|
@@ -32,18 +33,18 @@ export const commonFunctions = () => {
|
|
|
32
33
|
/**
|
|
33
34
|
* 데이터 타입에 따라 변환된 데이터을 반환한다.
|
|
34
35
|
*
|
|
35
|
-
* @param {
|
|
36
|
+
* @param {object} column - 컬럼 정보
|
|
36
37
|
* @param {number|string} value - 데이터
|
|
37
38
|
* @returns {number|string} 변환된 데이터
|
|
38
39
|
*/
|
|
39
|
-
const getConvertValue = (
|
|
40
|
+
const getConvertValue = (column, value) => {
|
|
40
41
|
let convertValue = value;
|
|
41
42
|
|
|
42
|
-
if (type === 'number') {
|
|
43
|
+
if (column.type === 'number') {
|
|
43
44
|
convertValue = numberWithComma(value);
|
|
44
45
|
convertValue = convertValue === false ? value : convertValue;
|
|
45
|
-
} else if (type === 'float') {
|
|
46
|
-
convertValue =
|
|
46
|
+
} else if (column.type === 'float') {
|
|
47
|
+
convertValue = convertValue.toFixed(column.decimal ?? 3);
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
return convertValue;
|
|
@@ -68,41 +69,48 @@ export const commonFunctions = () => {
|
|
|
68
69
|
};
|
|
69
70
|
|
|
70
71
|
export const scrollEvent = (params) => {
|
|
71
|
-
const {
|
|
72
|
-
|
|
72
|
+
const {
|
|
73
|
+
scrollInfo,
|
|
74
|
+
stores,
|
|
75
|
+
elementInfo,
|
|
76
|
+
resizeInfo,
|
|
77
|
+
pageInfo,
|
|
78
|
+
getPagingData,
|
|
79
|
+
updatePagingInfo,
|
|
80
|
+
} = params;
|
|
73
81
|
/**
|
|
74
82
|
* 수직 스크롤의 위치 계산 후 적용한다.
|
|
75
83
|
*/
|
|
76
|
-
const updateVScroll = () => {
|
|
84
|
+
const updateVScroll = (isScroll) => {
|
|
77
85
|
const bodyEl = elementInfo.body;
|
|
78
86
|
const rowHeight = resizeInfo.rowHeight;
|
|
79
87
|
if (bodyEl) {
|
|
88
|
+
let store = stores.store;
|
|
89
|
+
if (pageInfo.isClientPaging) {
|
|
90
|
+
store = getPagingData();
|
|
91
|
+
}
|
|
80
92
|
const rowCount = bodyEl.clientHeight > rowHeight
|
|
81
|
-
? Math.ceil(bodyEl.clientHeight / rowHeight) :
|
|
82
|
-
const totalScrollHeight =
|
|
93
|
+
? Math.ceil(bodyEl.clientHeight / rowHeight) : store.length;
|
|
94
|
+
const totalScrollHeight = store.length * rowHeight;
|
|
83
95
|
let firstVisibleIndex = Math.floor(bodyEl.scrollTop / rowHeight);
|
|
84
|
-
if (firstVisibleIndex >
|
|
96
|
+
if (firstVisibleIndex > store.length - 1) {
|
|
85
97
|
firstVisibleIndex = 0;
|
|
86
98
|
}
|
|
87
99
|
|
|
88
|
-
const lastVisibleIndex = firstVisibleIndex + rowCount;
|
|
100
|
+
const lastVisibleIndex = firstVisibleIndex + rowCount + 1;
|
|
89
101
|
const firstIndex = Math.max(firstVisibleIndex, 0);
|
|
90
102
|
const lastIndex = lastVisibleIndex;
|
|
91
103
|
|
|
92
|
-
stores.viewStore =
|
|
93
|
-
scrollInfo.hasVerticalScrollBar = rowCount <
|
|
104
|
+
stores.viewStore = store.slice(firstIndex, lastIndex);
|
|
105
|
+
scrollInfo.hasVerticalScrollBar = rowCount < store.length;
|
|
94
106
|
scrollInfo.vScrollTopHeight = firstIndex * rowHeight;
|
|
95
107
|
scrollInfo.vScrollBottomHeight = totalScrollHeight - (stores.viewStore.length * rowHeight)
|
|
96
108
|
- scrollInfo.vScrollTopHeight;
|
|
97
|
-
if (scrollInfo.vScrollBottomHeight === 0) {
|
|
109
|
+
if (isScroll && pageInfo.isInfinite && scrollInfo.vScrollBottomHeight === 0) {
|
|
98
110
|
pageInfo.prevPage = pageInfo.currentPage;
|
|
99
|
-
pageInfo.currentPage = Math.ceil(lastIndex / pageInfo.
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
dataCount: pageInfo.dataCount,
|
|
103
|
-
prevPage: pageInfo.prevPage,
|
|
104
|
-
currentPage: pageInfo.currentPage,
|
|
105
|
-
});
|
|
111
|
+
pageInfo.currentPage = Math.ceil(lastIndex / pageInfo.perPage) + 1;
|
|
112
|
+
pageInfo.startIndex = lastIndex;
|
|
113
|
+
updatePagingInfo({ onScrollEnd: true });
|
|
106
114
|
}
|
|
107
115
|
}
|
|
108
116
|
};
|
|
@@ -128,7 +136,7 @@ export const scrollEvent = (params) => {
|
|
|
128
136
|
const isVertical = !(scrollTop === lastTop);
|
|
129
137
|
|
|
130
138
|
if (isVertical && bodyEl?.clientHeight) {
|
|
131
|
-
updateVScroll();
|
|
139
|
+
updateVScroll(true);
|
|
132
140
|
}
|
|
133
141
|
|
|
134
142
|
if (isHorizontal) {
|
|
@@ -331,7 +339,7 @@ export const resizeEvent = (params) => {
|
|
|
331
339
|
|
|
332
340
|
export const clickEvent = (params) => {
|
|
333
341
|
const { emit } = getCurrentInstance();
|
|
334
|
-
const selectInfo = params;
|
|
342
|
+
const { selectInfo } = params;
|
|
335
343
|
const getClickedRowData = (event, row) => {
|
|
336
344
|
const tagName = event.target.tagName.toLowerCase();
|
|
337
345
|
let cellInfo = {};
|
|
@@ -354,17 +362,41 @@ export const clickEvent = (params) => {
|
|
|
354
362
|
* @param {object} event - 이벤트 객체
|
|
355
363
|
* @param {array} row - row 데이터
|
|
356
364
|
*/
|
|
365
|
+
let timer = null;
|
|
357
366
|
const onRowClick = (event, row) => {
|
|
358
367
|
if (event.target && event.target.parentElement
|
|
359
368
|
&& event.target.parentElement.classList.contains('row-checkbox-input')) {
|
|
360
369
|
return false;
|
|
361
370
|
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
selectInfo.
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
371
|
+
clearTimeout(timer);
|
|
372
|
+
timer = setTimeout(() => {
|
|
373
|
+
if (selectInfo.useSelect) {
|
|
374
|
+
const rowData = row[ROW_DATA_INDEX];
|
|
375
|
+
if (row[ROW_SELECT_INDEX]) {
|
|
376
|
+
row[ROW_SELECT_INDEX] = false;
|
|
377
|
+
if (selectInfo.multiple) {
|
|
378
|
+
if (event.ctrlKey) {
|
|
379
|
+
selectInfo.selectedRow.splice(selectInfo.selectedRow.indexOf(row[ROW_DATA_INDEX]), 1);
|
|
380
|
+
} else {
|
|
381
|
+
selectInfo.selectedRow = [rowData];
|
|
382
|
+
}
|
|
383
|
+
} else {
|
|
384
|
+
selectInfo.selectedRow = [];
|
|
385
|
+
}
|
|
386
|
+
} else {
|
|
387
|
+
row[ROW_SELECT_INDEX] = true;
|
|
388
|
+
if (event.ctrlKey
|
|
389
|
+
&& selectInfo.multiple
|
|
390
|
+
&& (!selectInfo.limitCount || selectInfo.limitCount > selectInfo.selectedRow.length)) {
|
|
391
|
+
selectInfo.selectedRow.push(rowData);
|
|
392
|
+
} else {
|
|
393
|
+
selectInfo.selectedRow = [rowData];
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
emit('update:selected', selectInfo.selectedRow);
|
|
397
|
+
emit('click-row', getClickedRowData(event, row));
|
|
398
|
+
}
|
|
399
|
+
}, 100);
|
|
368
400
|
return true;
|
|
369
401
|
};
|
|
370
402
|
/**
|
|
@@ -374,16 +406,14 @@ export const clickEvent = (params) => {
|
|
|
374
406
|
* @param {array} row - row 데이터
|
|
375
407
|
*/
|
|
376
408
|
const onRowDblClick = (event, row) => {
|
|
377
|
-
|
|
378
|
-
selectInfo.selectedRow = rowData;
|
|
379
|
-
emit('update:selected', rowData);
|
|
409
|
+
clearTimeout(timer);
|
|
380
410
|
emit('dblclick-row', getClickedRowData(event, row));
|
|
381
411
|
};
|
|
382
412
|
return { onRowClick, onRowDblClick };
|
|
383
413
|
};
|
|
384
414
|
|
|
385
415
|
export const checkEvent = (params) => {
|
|
386
|
-
const { checkInfo, stores } = params;
|
|
416
|
+
const { checkInfo, stores, pageInfo, getPagingData } = params;
|
|
387
417
|
const { emit } = getCurrentInstance();
|
|
388
418
|
/**
|
|
389
419
|
* row에 대한 체크 상태를 해제한다.
|
|
@@ -413,13 +443,13 @@ export const checkEvent = (params) => {
|
|
|
413
443
|
if (row[ROW_CHECK_INDEX]) {
|
|
414
444
|
if (checkInfo.useCheckbox.mode === 'single') {
|
|
415
445
|
checkInfo.checkedRows = [row[ROW_DATA_INDEX]];
|
|
416
|
-
checkInfo.checkedIndex.clear();
|
|
417
446
|
} else {
|
|
418
447
|
checkInfo.checkedRows.push(row[ROW_DATA_INDEX]);
|
|
419
448
|
}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
449
|
+
let store = stores.store;
|
|
450
|
+
if (pageInfo.isClientPaging) {
|
|
451
|
+
store = getPagingData();
|
|
452
|
+
}
|
|
423
453
|
const isAllChecked = store.every(d => d[ROW_CHECK_INDEX]);
|
|
424
454
|
if (store.length && isAllChecked) {
|
|
425
455
|
checkInfo.isHeaderChecked = true;
|
|
@@ -427,10 +457,8 @@ export const checkEvent = (params) => {
|
|
|
427
457
|
} else {
|
|
428
458
|
if (checkInfo.useCheckbox.mode === 'single') {
|
|
429
459
|
checkInfo.checkedRows = [];
|
|
430
|
-
checkInfo.checkedIndex.clear();
|
|
431
460
|
} else {
|
|
432
461
|
checkInfo.checkedRows.splice(checkInfo.checkedRows.indexOf(row[ROW_DATA_INDEX]), 1);
|
|
433
|
-
checkInfo.checkedIndex.delete(row[ROW_INDEX]);
|
|
434
462
|
}
|
|
435
463
|
checkInfo.isHeaderChecked = false;
|
|
436
464
|
}
|
|
@@ -445,18 +473,17 @@ export const checkEvent = (params) => {
|
|
|
445
473
|
*/
|
|
446
474
|
const onCheckAll = (event) => {
|
|
447
475
|
const isHeaderChecked = checkInfo.isHeaderChecked;
|
|
448
|
-
|
|
476
|
+
let store = stores.store;
|
|
477
|
+
if (pageInfo.isClientPaging) {
|
|
478
|
+
store = getPagingData();
|
|
479
|
+
}
|
|
449
480
|
store.forEach((row) => {
|
|
450
481
|
if (isHeaderChecked) {
|
|
451
482
|
if (!checkInfo.checkedRows.includes(row[ROW_DATA_INDEX])) {
|
|
452
483
|
checkInfo.checkedRows.push(row[ROW_DATA_INDEX]);
|
|
453
484
|
}
|
|
454
|
-
if (!checkInfo.checkedIndex.has(row[ROW_INDEX])) {
|
|
455
|
-
checkInfo.checkedIndex.add(row[ROW_INDEX]);
|
|
456
|
-
}
|
|
457
485
|
} else {
|
|
458
486
|
checkInfo.checkedRows.splice(checkInfo.checkedRows.indexOf(row[ROW_DATA_INDEX]), 1);
|
|
459
|
-
checkInfo.checkedIndex.delete(row[ROW_INDEX]);
|
|
460
487
|
}
|
|
461
488
|
row[ROW_CHECK_INDEX] = isHeaderChecked;
|
|
462
489
|
});
|
|
@@ -467,7 +494,7 @@ export const checkEvent = (params) => {
|
|
|
467
494
|
};
|
|
468
495
|
|
|
469
496
|
export const sortEvent = (params) => {
|
|
470
|
-
const { sortInfo, stores, getColumnIndex } = params;
|
|
497
|
+
const { sortInfo, stores, getColumnIndex, updatePagingInfo } = params;
|
|
471
498
|
const { props } = getCurrentInstance();
|
|
472
499
|
function OrderQueue() {
|
|
473
500
|
this.orders = ['asc', 'desc', 'init'];
|
|
@@ -491,6 +518,7 @@ export const sortEvent = (params) => {
|
|
|
491
518
|
order.enqueue(sortInfo.sortOrder);
|
|
492
519
|
|
|
493
520
|
sortInfo.isSorting = true;
|
|
521
|
+
updatePagingInfo({ onSort: true });
|
|
494
522
|
}
|
|
495
523
|
};
|
|
496
524
|
/**
|
|
@@ -548,9 +576,12 @@ export const filterEvent = (params) => {
|
|
|
548
576
|
filterInfo,
|
|
549
577
|
stores,
|
|
550
578
|
checkInfo,
|
|
579
|
+
pageInfo,
|
|
551
580
|
getColumnIndex,
|
|
552
581
|
getConvertValue,
|
|
553
582
|
updateVScroll,
|
|
583
|
+
getPagingData,
|
|
584
|
+
updatePagingInfo,
|
|
554
585
|
} = params;
|
|
555
586
|
/**
|
|
556
587
|
* 해당 컬럼에 대한 필터 팝업을 보여준다.
|
|
@@ -743,13 +774,13 @@ export const filterEvent = (params) => {
|
|
|
743
774
|
for (let ix = 0; ix < stores.orderedColumns.length; ix++) {
|
|
744
775
|
const column = stores.orderedColumns[ix] || {};
|
|
745
776
|
let columnValue = row[ROW_DATA_INDEX][ix];
|
|
746
|
-
|
|
777
|
+
column.type = column.type || 'string';
|
|
747
778
|
if (columnValue) {
|
|
748
779
|
if (typeof columnValue === 'object') {
|
|
749
780
|
columnValue = columnValue[column.field];
|
|
750
781
|
}
|
|
751
782
|
if (!column.hide && (column?.searchable === undefined || column?.searchable)) {
|
|
752
|
-
columnValue = getConvertValue(
|
|
783
|
+
columnValue = getConvertValue(column, columnValue).toString();
|
|
753
784
|
isShow = columnValue.toLowerCase().includes(searchWord.toString().toLowerCase());
|
|
754
785
|
if (isShow) {
|
|
755
786
|
break;
|
|
@@ -774,6 +805,12 @@ export const filterEvent = (params) => {
|
|
|
774
805
|
} else {
|
|
775
806
|
checkInfo.isHeaderChecked = false;
|
|
776
807
|
}
|
|
808
|
+
if (!searchWord && pageInfo.isClientPaging && pageInfo.prevPage) {
|
|
809
|
+
pageInfo.currentPage = 1;
|
|
810
|
+
stores.pagingStore = getPagingData();
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
updatePagingInfo({ onSearch: true });
|
|
777
814
|
updateVScroll();
|
|
778
815
|
}, 500);
|
|
779
816
|
};
|
|
@@ -865,30 +902,25 @@ export const storeEvent = (params) => {
|
|
|
865
902
|
/**
|
|
866
903
|
* 전달된 데이터를 내부 store 및 속성에 저장한다.
|
|
867
904
|
*
|
|
868
|
-
* @param {array}
|
|
905
|
+
* @param {array} rows - row 데이터
|
|
869
906
|
* @param {boolean} isMakeIndex - 인덱스 생성 유무
|
|
870
907
|
*/
|
|
871
|
-
const setStore = (
|
|
872
|
-
const store = [];
|
|
873
|
-
let checked;
|
|
874
|
-
let selected = false;
|
|
908
|
+
const setStore = (rows, isMakeIndex = true) => {
|
|
875
909
|
if (isMakeIndex) {
|
|
910
|
+
const store = [];
|
|
876
911
|
let hasUnChecked = false;
|
|
877
|
-
|
|
878
|
-
checked = props.checked.includes(
|
|
912
|
+
rows.forEach((row, idx) => {
|
|
913
|
+
const checked = props.checked.includes(row);
|
|
914
|
+
let selected = false;
|
|
915
|
+
if (selectInfo.useSelect) {
|
|
916
|
+
selected = props.selected.includes(row);
|
|
917
|
+
}
|
|
879
918
|
if (!checked) {
|
|
880
919
|
hasUnChecked = true;
|
|
881
920
|
}
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
}
|
|
886
|
-
store.push([ix, checked, value[ix]]);
|
|
887
|
-
}
|
|
888
|
-
if (!selected) {
|
|
889
|
-
selectInfo.selectedRow = [];
|
|
890
|
-
}
|
|
891
|
-
checkInfo.isHeaderChecked = value.length > 0 ? !hasUnChecked : false;
|
|
921
|
+
store.push([idx, checked, row, selected]);
|
|
922
|
+
});
|
|
923
|
+
checkInfo.isHeaderChecked = rows.length > 0 ? !hasUnChecked : false;
|
|
892
924
|
stores.originStore = store;
|
|
893
925
|
}
|
|
894
926
|
if (filterInfo.isFiltering) {
|
|
@@ -901,18 +933,65 @@ export const storeEvent = (params) => {
|
|
|
901
933
|
updateVScroll();
|
|
902
934
|
}
|
|
903
935
|
};
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
936
|
+
return { setStore };
|
|
937
|
+
};
|
|
938
|
+
|
|
939
|
+
export const pagingEvent = (params) => {
|
|
940
|
+
const { emit } = getCurrentInstance();
|
|
941
|
+
const {
|
|
942
|
+
stores,
|
|
943
|
+
pageInfo,
|
|
944
|
+
sortInfo,
|
|
945
|
+
filterInfo,
|
|
946
|
+
elementInfo,
|
|
947
|
+
clearCheckInfo,
|
|
948
|
+
} = params;
|
|
949
|
+
const getPagingData = () => {
|
|
950
|
+
const start = (pageInfo.currentPage - 1) * pageInfo.perPage;
|
|
951
|
+
const end = parseInt(start, 10) + parseInt(pageInfo.perPage, 10);
|
|
952
|
+
return stores.store.slice(start, end);
|
|
953
|
+
};
|
|
954
|
+
const updatePagingInfo = (eventName) => {
|
|
955
|
+
emit('page-change', {
|
|
956
|
+
eventName,
|
|
957
|
+
pageInfo: {
|
|
958
|
+
currentPage: pageInfo.currentPage,
|
|
959
|
+
prevPage: pageInfo.prevPage,
|
|
960
|
+
startIndex: pageInfo.startIndex,
|
|
961
|
+
total: pageInfo.total,
|
|
962
|
+
perPage: pageInfo.perPage,
|
|
963
|
+
},
|
|
964
|
+
sortInfo: {
|
|
965
|
+
field: sortInfo.sortField,
|
|
966
|
+
order: sortInfo.sortOrder,
|
|
967
|
+
},
|
|
968
|
+
searchInfo: {
|
|
969
|
+
searchWord: filterInfo.searchWord,
|
|
970
|
+
searchColumns: stores.orderedColumns
|
|
971
|
+
.filter(c => !c.hide && (c?.searchable === undefined || c?.searchable))
|
|
972
|
+
.map(d => d.field),
|
|
973
|
+
},
|
|
974
|
+
});
|
|
975
|
+
if (pageInfo.isInfinite && (eventName?.onSearch || eventName?.onSort)) {
|
|
976
|
+
pageInfo.currentPage = 1;
|
|
977
|
+
elementInfo.body.scrollTop = 0;
|
|
978
|
+
clearCheckInfo();
|
|
979
|
+
}
|
|
980
|
+
};
|
|
981
|
+
const changePage = (beforeVal) => {
|
|
982
|
+
if (pageInfo.isClientPaging) {
|
|
983
|
+
pageInfo.prevPage = beforeVal;
|
|
984
|
+
if (stores.store.length <= pageInfo.perPage) {
|
|
985
|
+
stores.pagingStore = stores.store;
|
|
986
|
+
} else {
|
|
987
|
+
const start = (pageInfo.currentPage - 1) * pageInfo.perPage;
|
|
988
|
+
const end = parseInt(start, 10) + parseInt(pageInfo.perPage, 10);
|
|
989
|
+
stores.pagingStore = stores.store.slice(start, end);
|
|
990
|
+
elementInfo.body.scrollTop = 0;
|
|
991
|
+
pageInfo.startIndex = start;
|
|
992
|
+
}
|
|
915
993
|
}
|
|
994
|
+
updatePagingInfo({ onChangePage: true });
|
|
916
995
|
};
|
|
917
|
-
return {
|
|
996
|
+
return { getPagingData, updatePagingInfo, changePage };
|
|
918
997
|
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<nav class="pagination">
|
|
3
3
|
<!-- Page Info -->
|
|
4
|
-
<small v-if="
|
|
4
|
+
<small v-if="showPageInfo" class="pagination-info">
|
|
5
5
|
<template v-if="perPage === 1">
|
|
6
|
-
{{
|
|
6
|
+
{{ firstData }} / {{ total }}
|
|
7
7
|
</template>
|
|
8
8
|
<template v-else>
|
|
9
|
-
{{
|
|
10
|
-
/ {{
|
|
9
|
+
{{ firstData }} - {{ Math.min(current * perPage, total) }}
|
|
10
|
+
/ {{ total }}
|
|
11
11
|
</template>
|
|
12
12
|
</small>
|
|
13
13
|
<ul class="pagination-list" :style="listClasses">
|
|
@@ -49,7 +49,6 @@
|
|
|
49
49
|
<script>
|
|
50
50
|
import { computed, nextTick, watch } from 'vue';
|
|
51
51
|
import EvIcon from '@/components/icon/Icon';
|
|
52
|
-
import { numberWithComma } from '@/common/utils';
|
|
53
52
|
import pageButton from './pageButton';
|
|
54
53
|
|
|
55
54
|
export default {
|
|
@@ -59,8 +58,14 @@ export default {
|
|
|
59
58
|
pageButton,
|
|
60
59
|
},
|
|
61
60
|
props: {
|
|
62
|
-
total:
|
|
63
|
-
|
|
61
|
+
total: {
|
|
62
|
+
type: [Number, String],
|
|
63
|
+
default: 0,
|
|
64
|
+
},
|
|
65
|
+
visiblePage: {
|
|
66
|
+
type: [Number, String],
|
|
67
|
+
default: 8,
|
|
68
|
+
},
|
|
64
69
|
perPage: {
|
|
65
70
|
type: [Number, String],
|
|
66
71
|
default: 20,
|
|
@@ -69,8 +74,10 @@ export default {
|
|
|
69
74
|
type: [Number, String],
|
|
70
75
|
default: 1,
|
|
71
76
|
},
|
|
72
|
-
|
|
73
|
-
|
|
77
|
+
showPageInfo: {
|
|
78
|
+
type: Boolean,
|
|
79
|
+
default: false,
|
|
80
|
+
},
|
|
74
81
|
order: {
|
|
75
82
|
type: String,
|
|
76
83
|
default: 'left',
|
|
@@ -82,9 +89,10 @@ export default {
|
|
|
82
89
|
change: null,
|
|
83
90
|
},
|
|
84
91
|
setup(props, { emit }) {
|
|
85
|
-
const visiblePage = computed(() => props.visiblePage
|
|
92
|
+
const visiblePage = computed(() => (props.visiblePage > 7 ? props.visiblePage : 7));
|
|
86
93
|
const current = computed(() => props.modelValue);
|
|
87
|
-
const pageCount = computed(() =>
|
|
94
|
+
const pageCount = computed(() => (props.total === 0
|
|
95
|
+
? 1 : Math.ceil(props.total / props.perPage)));
|
|
88
96
|
const hasPrev = computed(() => current.value > 1);
|
|
89
97
|
const hasNext = computed(() => current.value < pageCount.value);
|
|
90
98
|
const firstData = computed(() => {
|
|
@@ -168,7 +176,7 @@ export default {
|
|
|
168
176
|
() => pageCount.value,
|
|
169
177
|
(value) => {
|
|
170
178
|
if (current.value > value) {
|
|
171
|
-
changePage(
|
|
179
|
+
changePage(value);
|
|
172
180
|
}
|
|
173
181
|
},
|
|
174
182
|
);
|
|
@@ -190,7 +198,6 @@ export default {
|
|
|
190
198
|
current,
|
|
191
199
|
changePage,
|
|
192
200
|
getPage,
|
|
193
|
-
numberWithComma,
|
|
194
201
|
};
|
|
195
202
|
},
|
|
196
203
|
};
|
|
@@ -206,9 +213,7 @@ export default {
|
|
|
206
213
|
padding-right: 10px;
|
|
207
214
|
background: center center no-repeat;
|
|
208
215
|
background-size: 16px;
|
|
209
|
-
background-color: #FFFFFF;
|
|
210
216
|
cursor: pointer;
|
|
211
|
-
color: #303133;
|
|
212
217
|
&:hover {
|
|
213
218
|
color: #1A6AFE;
|
|
214
219
|
}
|
|
@@ -238,7 +243,6 @@ export default {
|
|
|
238
243
|
cursor: not-allowed;
|
|
239
244
|
opacity: 0.5;
|
|
240
245
|
color: #C0C4CC;
|
|
241
|
-
background-color: #FFFFFF;
|
|
242
246
|
}
|
|
243
247
|
&-list {
|
|
244
248
|
display: flex;
|
|
@@ -255,7 +259,6 @@ export default {
|
|
|
255
259
|
padding: 0 4px;
|
|
256
260
|
justify-content: center;
|
|
257
261
|
align-items: center;
|
|
258
|
-
background: #FFFFFF;
|
|
259
262
|
font-size: 14px;
|
|
260
263
|
min-width: 32px;
|
|
261
264
|
line-height: 32px;
|