@lx-frontend/wrap-element-ui 1.0.1-beta.1 → 1.0.1-beta.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/package.json +2 -3
- package/src/components/EditableTable/index.less +34 -26
- package/src/components/EditableTable/index.vue +108 -35
- package/src/components/EditableTable/types.ts +32 -10
- package/src/components/EditableTable/useColumnHeaderOperation.ts +166 -28
- package/src/components/EditableTable/useDefaultOperation.ts +10 -10
- package/src/components/EditableTable/useDragSort.ts +4 -5
- package/src/components/EditableTable/usePagination.ts +4 -7
- package/src/components/EditableTable/useRowBgColor.ts +3 -3
- package/src/components/EditableTable/useViewSetting.ts +53 -1
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lx-frontend/wrap-element-ui",
|
|
3
|
-
"version": "1.0.1-beta.
|
|
3
|
+
"version": "1.0.1-beta.3",
|
|
4
4
|
"description": "wrap-element-ui",
|
|
5
5
|
"author": "",
|
|
6
|
-
"main": "
|
|
6
|
+
"main": "src/components/index.ts",
|
|
7
7
|
"private": false,
|
|
8
8
|
"scripts": {
|
|
9
9
|
"clean": "rimraf dist",
|
|
@@ -18,7 +18,6 @@
|
|
|
18
18
|
"lint": "eslint src"
|
|
19
19
|
},
|
|
20
20
|
"files": [
|
|
21
|
-
"dist",
|
|
22
21
|
"README.md",
|
|
23
22
|
"package.json",
|
|
24
23
|
"src/components"
|
|
@@ -180,6 +180,31 @@
|
|
|
180
180
|
border-right: 2px #e4e8ef solid;
|
|
181
181
|
}
|
|
182
182
|
}
|
|
183
|
+
|
|
184
|
+
.el-table-filter,
|
|
185
|
+
th.el-table__cell .el-table__column-filter-trigger,
|
|
186
|
+
th.is-sortable .caret-wrapper {
|
|
187
|
+
display: none;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.el-table__body tr.current-row > td,
|
|
191
|
+
.el-table__body tr.hover-row > td {
|
|
192
|
+
background-color: #fafafa;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
table tbody tr td {
|
|
196
|
+
& .el-date-editor.el-input {
|
|
197
|
+
width: 100%;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
& .cell {
|
|
201
|
+
font-size: 14px;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.el-table__fixed-body-wrapper {
|
|
206
|
+
background: #fff;
|
|
207
|
+
}
|
|
183
208
|
}
|
|
184
209
|
|
|
185
210
|
.view-setting {
|
|
@@ -207,7 +232,7 @@
|
|
|
207
232
|
padding: 0px;
|
|
208
233
|
|
|
209
234
|
.el-dialog__body {
|
|
210
|
-
max-height:
|
|
235
|
+
max-height: 70vh;
|
|
211
236
|
}
|
|
212
237
|
|
|
213
238
|
.el-dialog__body {
|
|
@@ -497,6 +522,12 @@
|
|
|
497
522
|
background-color: @--theme-blue--;
|
|
498
523
|
border-color: @--theme-blue--;
|
|
499
524
|
}
|
|
525
|
+
|
|
526
|
+
.el-checkbox__input.is-checked .el-checkbox__inner,
|
|
527
|
+
.el-radio__input.is-checked .el-radio__inner {
|
|
528
|
+
background: #2468f2;
|
|
529
|
+
border-color: #2468f2;
|
|
530
|
+
}
|
|
500
531
|
}
|
|
501
532
|
|
|
502
533
|
.btn-pointer {
|
|
@@ -576,6 +607,8 @@
|
|
|
576
607
|
margin-top: 12px;
|
|
577
608
|
|
|
578
609
|
& .el-pagination {
|
|
610
|
+
padding: 0;
|
|
611
|
+
|
|
579
612
|
.el-pager li.number {
|
|
580
613
|
background-color: #fff;
|
|
581
614
|
border: 1px solid #d6dbe3;
|
|
@@ -605,26 +638,7 @@
|
|
|
605
638
|
}
|
|
606
639
|
}
|
|
607
640
|
|
|
608
|
-
.el-table__body tr.current-row > td,
|
|
609
|
-
.el-table__body tr.hover-row > td {
|
|
610
|
-
background-color: #fafafa;
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
.el-table-filter,
|
|
614
|
-
th.el-table__cell .el-table__column-filter-trigger,
|
|
615
|
-
th.is-sortable .caret-wrapper {
|
|
616
|
-
display: none;
|
|
617
|
-
}
|
|
618
641
|
|
|
619
|
-
table tbody tr td {
|
|
620
|
-
& .el-date-editor.el-input {
|
|
621
|
-
width: 100%;
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
& .cell {
|
|
625
|
-
font-size: 14px;
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
642
|
|
|
629
643
|
.editable-table {
|
|
630
644
|
& table th {
|
|
@@ -674,12 +688,6 @@ table tbody tr td {
|
|
|
674
688
|
}
|
|
675
689
|
}
|
|
676
690
|
|
|
677
|
-
.el-select-dropdown {
|
|
678
|
-
&__item {
|
|
679
|
-
text-align: center;
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
|
|
683
691
|
.el-dialog__header {
|
|
684
692
|
display: flex;
|
|
685
693
|
justify-content: space-between;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="editable-table">
|
|
3
3
|
<div class="view-setting">
|
|
4
|
-
<div
|
|
4
|
+
<div
|
|
5
|
+
v-if="!hideViewSettingBtn"
|
|
6
|
+
class="view-setting__btn-wrapper"
|
|
7
|
+
>
|
|
5
8
|
<div
|
|
6
9
|
class="view-setting__btn btn-pointer"
|
|
7
10
|
@click="handleViewSettingShow"
|
|
@@ -17,6 +20,7 @@
|
|
|
17
20
|
title="显示设置"
|
|
18
21
|
:visible.sync="viewSettingVisible"
|
|
19
22
|
width="750px"
|
|
23
|
+
top="12vh"
|
|
20
24
|
:close-on-click-modal="false"
|
|
21
25
|
:append-to-body="true"
|
|
22
26
|
custom-class="view-setting__dialog"
|
|
@@ -51,8 +55,9 @@
|
|
|
51
55
|
<div class="view-setting__content-right-frize">
|
|
52
56
|
冻结前
|
|
53
57
|
<el-input
|
|
54
|
-
v-model="leftFixedColumnCount"
|
|
55
58
|
class="view-setting__content-right-input"
|
|
59
|
+
:value="tempLeftFixedColumnCount"
|
|
60
|
+
@input="handleInputTempLeftFixedColumnCount"
|
|
56
61
|
/>
|
|
57
62
|
列
|
|
58
63
|
</div>
|
|
@@ -218,7 +223,7 @@
|
|
|
218
223
|
:key="column.prop + index"
|
|
219
224
|
resizable
|
|
220
225
|
class-name="editable-table__data-column"
|
|
221
|
-
:filtered-value="filteredValue[column.prop]
|
|
226
|
+
:filtered-value="Array.isArray(filteredValue[column.prop]) ? filteredValue[column.prop] : []"
|
|
222
227
|
v-bind="getColumnBindProps(column)"
|
|
223
228
|
>
|
|
224
229
|
<template
|
|
@@ -267,7 +272,7 @@
|
|
|
267
272
|
</div>
|
|
268
273
|
</div>
|
|
269
274
|
<div
|
|
270
|
-
v-if="column.
|
|
275
|
+
v-if="column.search && !Array.isArray(column.search)"
|
|
271
276
|
class="sort-filter__search"
|
|
272
277
|
>
|
|
273
278
|
<div class="sort-filter__search-title">
|
|
@@ -279,19 +284,41 @@
|
|
|
279
284
|
placeholder="请输入内容"
|
|
280
285
|
/>
|
|
281
286
|
</div>
|
|
287
|
+
|
|
282
288
|
<div
|
|
283
|
-
v-if="column.
|
|
289
|
+
v-if="column.search && Array.isArray(column.search)"
|
|
290
|
+
class="sort-filter__search"
|
|
291
|
+
style="display: flex;flex-direction: column;gap: 12px;"
|
|
292
|
+
>
|
|
293
|
+
<div
|
|
294
|
+
v-for="item in column.search"
|
|
295
|
+
:key="item.prop"
|
|
296
|
+
>
|
|
297
|
+
<div class="sort-filter__search-title">
|
|
298
|
+
{{ item.label }}
|
|
299
|
+
</div>
|
|
300
|
+
<el-input
|
|
301
|
+
v-model="tempSearchValue[item.prop]"
|
|
302
|
+
class="sort-filter__search-input"
|
|
303
|
+
placeholder="请输入内容"
|
|
304
|
+
/>
|
|
305
|
+
</div>
|
|
306
|
+
</div>
|
|
307
|
+
|
|
308
|
+
<div
|
|
309
|
+
v-if="column.filters && ((Array.isArray(column.filters) ? column.filters : column.filters.options).length > 0)"
|
|
284
310
|
class="sort-filter__filter"
|
|
285
311
|
>
|
|
286
312
|
<div class="sort-filter__filter-title">
|
|
287
313
|
筛选
|
|
288
314
|
</div>
|
|
289
315
|
<el-checkbox-group
|
|
316
|
+
v-if="column.filters && (Array.isArray(column.filters) || column.filters.type === 'checkbox')"
|
|
290
317
|
v-model="tempFilteredValue[column.prop]"
|
|
291
318
|
class="sort-filter__filter-checkbox-group"
|
|
292
319
|
>
|
|
293
320
|
<el-checkbox
|
|
294
|
-
v-for="item in column.filters"
|
|
321
|
+
v-for="item in (Array.isArray(column.filters) ? column.filters : column.filters.options)"
|
|
295
322
|
:key="item.value"
|
|
296
323
|
:label="item.value"
|
|
297
324
|
class="sort-filter__filter-checkbox"
|
|
@@ -304,6 +331,25 @@
|
|
|
304
331
|
</slot>
|
|
305
332
|
</el-checkbox>
|
|
306
333
|
</el-checkbox-group>
|
|
334
|
+
|
|
335
|
+
<el-radio-group
|
|
336
|
+
v-if="column.filters && !Array.isArray(column.filters) && column.filters.type === 'radio'"
|
|
337
|
+
v-model="tempFilteredValue[column.prop]"
|
|
338
|
+
style="display: flex;flex-direction: column;gap: 6px;"
|
|
339
|
+
>
|
|
340
|
+
<el-radio
|
|
341
|
+
v-for="item in column.filters.options"
|
|
342
|
+
:key="item.value"
|
|
343
|
+
:label="item.value"
|
|
344
|
+
>
|
|
345
|
+
<slot
|
|
346
|
+
:name="column.prop + '-filter-item'"
|
|
347
|
+
v-bind="item"
|
|
348
|
+
>
|
|
349
|
+
{{ item.text }}
|
|
350
|
+
</slot>
|
|
351
|
+
</el-radio>
|
|
352
|
+
</el-radio-group>
|
|
307
353
|
</div>
|
|
308
354
|
<div
|
|
309
355
|
v-if="column.summary"
|
|
@@ -339,7 +385,7 @@
|
|
|
339
385
|
<el-button
|
|
340
386
|
class="sort-filter__confirm-btn"
|
|
341
387
|
type="primary"
|
|
342
|
-
@click="handleHeaderOperationConfirm(scope)"
|
|
388
|
+
@click="handleHeaderOperationConfirm(column, scope)"
|
|
343
389
|
>
|
|
344
390
|
确定
|
|
345
391
|
</el-button>
|
|
@@ -538,7 +584,7 @@
|
|
|
538
584
|
:page-sizes="[10, 15, 30, 60, 100]"
|
|
539
585
|
:page-size.sync="pageSize"
|
|
540
586
|
:pager-count="11"
|
|
541
|
-
:current-page
|
|
587
|
+
:current-page="currentPage"
|
|
542
588
|
:total="total"
|
|
543
589
|
@size-change="handlePageSizeChange"
|
|
544
590
|
@current-change="handleCurrPageChange"
|
|
@@ -565,7 +611,7 @@ interface IProps {
|
|
|
565
611
|
dataList: ITableDataItem[];
|
|
566
612
|
/** 列配置 */
|
|
567
613
|
columnConfig: IColumnConfig[];
|
|
568
|
-
/** 是否展示展开行 */
|
|
614
|
+
/** 是否展示展开行 */
|
|
569
615
|
hasExpandRow?: boolean;
|
|
570
616
|
/** 是否展示序号 */
|
|
571
617
|
hasIndexColumn?: boolean;
|
|
@@ -585,6 +631,16 @@ interface IProps {
|
|
|
585
631
|
dragSemiRange?: number;
|
|
586
632
|
/** 是否显示加载 */
|
|
587
633
|
loading?: boolean;
|
|
634
|
+
/** 是否隐藏显示设置按钮 */
|
|
635
|
+
hideViewSettingBtn?: boolean
|
|
636
|
+
/** 设置的缓存的key */
|
|
637
|
+
settingStorgeKey?: string
|
|
638
|
+
/** 前端排序,默认关闭 */
|
|
639
|
+
localSort?: boolean
|
|
640
|
+
/** 前端过滤,默认关闭 */
|
|
641
|
+
localFilter?: boolean
|
|
642
|
+
/** 页码 */
|
|
643
|
+
currentPage: number
|
|
588
644
|
}
|
|
589
645
|
|
|
590
646
|
interface IEmits {
|
|
@@ -606,6 +662,10 @@ interface IEmits {
|
|
|
606
662
|
(e: 'row-edit-cancel', param: { row: any; page: number; size: number;}): void
|
|
607
663
|
/** 页码改变 */
|
|
608
664
|
(e: 'page-change', param: { page: number, size: number }): void
|
|
665
|
+
/** 查询 */
|
|
666
|
+
(e: 'search', param: Record<string, any>): void
|
|
667
|
+
/** 排序 */
|
|
668
|
+
(e: 'sort-change', param: { order: 'descending' | 'ascending' | null, prop: string }): void
|
|
609
669
|
}
|
|
610
670
|
|
|
611
671
|
const props = withDefaults(defineProps<IProps>(), {
|
|
@@ -620,7 +680,12 @@ const props = withDefaults(defineProps<IProps>(), {
|
|
|
620
680
|
colorList: () => [],
|
|
621
681
|
leftFixedCount: 1,
|
|
622
682
|
dragSemiRange: 15,
|
|
623
|
-
loading: false
|
|
683
|
+
loading: false,
|
|
684
|
+
hideViewSettingBtn: false,
|
|
685
|
+
settingStorgeKey: '',
|
|
686
|
+
localSort: false,
|
|
687
|
+
localFilter: false,
|
|
688
|
+
currentPage: 1,
|
|
624
689
|
})
|
|
625
690
|
|
|
626
691
|
// 同defineProps一样,不支持泛型参数从外部导入
|
|
@@ -640,16 +705,14 @@ const actualColumns = computed(() => {
|
|
|
640
705
|
isColumnSortable: rawItem.sortable,
|
|
641
706
|
sortable: inSorting.value ? rawItem.sortable : false
|
|
642
707
|
};
|
|
643
|
-
if (
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
item.fixed = undefined;
|
|
650
|
-
}
|
|
651
|
-
res.push(item);
|
|
708
|
+
if (cnt > 0) {
|
|
709
|
+
item.fixed = 'left';
|
|
710
|
+
// eslint-disable-next-line no-plusplus
|
|
711
|
+
cnt--;
|
|
712
|
+
} else {
|
|
713
|
+
item.fixed = undefined;
|
|
652
714
|
}
|
|
715
|
+
res.push(item);
|
|
653
716
|
}
|
|
654
717
|
|
|
655
718
|
// 使用默认操作项,添加默认操作列。该列在编辑模式下隐藏
|
|
@@ -675,9 +738,8 @@ const beforePageChange = () => {
|
|
|
675
738
|
}
|
|
676
739
|
const {
|
|
677
740
|
pageSize,
|
|
678
|
-
currentPage,
|
|
679
741
|
handleCurrPageChange,
|
|
680
|
-
handlePageSizeChange
|
|
742
|
+
handlePageSizeChange,
|
|
681
743
|
} = usePagination({
|
|
682
744
|
emit,
|
|
683
745
|
beforePageChange
|
|
@@ -717,7 +779,7 @@ const {
|
|
|
717
779
|
emit,
|
|
718
780
|
tableDomRef,
|
|
719
781
|
pageSize,
|
|
720
|
-
|
|
782
|
+
props,
|
|
721
783
|
hasExpandRow: props.hasExpandRow
|
|
722
784
|
})
|
|
723
785
|
|
|
@@ -727,6 +789,8 @@ const {
|
|
|
727
789
|
columnsToBeShown,
|
|
728
790
|
viewSettingVisible,
|
|
729
791
|
leftFixedColumnCount,
|
|
792
|
+
tempLeftFixedColumnCount,
|
|
793
|
+
handleInputTempLeftFixedColumnCount,
|
|
730
794
|
handleViewSettingShow,
|
|
731
795
|
handleViewSettingClose,
|
|
732
796
|
handleViewSettingConfirm
|
|
@@ -739,6 +803,9 @@ const {
|
|
|
739
803
|
|
|
740
804
|
/************ 列头部操作相关 ************ */
|
|
741
805
|
const {
|
|
806
|
+
setSort,
|
|
807
|
+
clearSort,
|
|
808
|
+
setSearchParams,
|
|
742
809
|
isColumnHeadActive,
|
|
743
810
|
handleSort,
|
|
744
811
|
handleHeaderPopoverShow,
|
|
@@ -756,11 +823,13 @@ const {
|
|
|
756
823
|
sortingColumn,
|
|
757
824
|
isColumnFiltering,
|
|
758
825
|
searchValue,
|
|
759
|
-
inSorting
|
|
826
|
+
inSorting,
|
|
760
827
|
} = useColumnHeaderOperation({
|
|
761
828
|
tableDomRef,
|
|
762
829
|
sortFilterPopoverRef,
|
|
763
|
-
props
|
|
830
|
+
props,
|
|
831
|
+
emit,
|
|
832
|
+
showingColumns,
|
|
764
833
|
})
|
|
765
834
|
|
|
766
835
|
/************ 表格行拖拽和显示设置列拖拽 ************ */
|
|
@@ -787,7 +856,6 @@ useDragSort({
|
|
|
787
856
|
props,
|
|
788
857
|
viewSettingDragSortOptions,
|
|
789
858
|
beforeDragStart,
|
|
790
|
-
currentPage,
|
|
791
859
|
pageSize,
|
|
792
860
|
currScope,
|
|
793
861
|
tableDomRef,
|
|
@@ -798,18 +866,10 @@ const doTableLayout = async () => {
|
|
|
798
866
|
tableDomRef.value?.doLayout();
|
|
799
867
|
}
|
|
800
868
|
|
|
801
|
-
watch(
|
|
802
|
-
() => props.columnConfig,
|
|
803
|
-
(val) => {
|
|
804
|
-
showingColumns.value = val.map(c => c.prop);
|
|
805
|
-
},
|
|
806
|
-
{ immediate: true }
|
|
807
|
-
)
|
|
808
|
-
|
|
809
869
|
// 过滤出自定义属性,将其它属性全部透传给 el-table-column
|
|
810
870
|
const getColumnBindProps = (column: IColumnConfig) => {
|
|
811
871
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
812
|
-
const { editAble, editType, slotName, inputType, options, ...rest } = column;
|
|
872
|
+
const { editAble, editType, slotName, inputType, options, filters, ...rest } = column;
|
|
813
873
|
return rest;
|
|
814
874
|
}
|
|
815
875
|
|
|
@@ -832,7 +892,20 @@ const handleColumnClose = (item) => {
|
|
|
832
892
|
|
|
833
893
|
defineExpose({
|
|
834
894
|
closeAllExpandedRows,
|
|
835
|
-
|
|
895
|
+
openViewSetting: handleViewSettingShow,
|
|
896
|
+
elTableRef: tableDomRef,
|
|
897
|
+
setSort,
|
|
898
|
+
clearSort,
|
|
899
|
+
setSearchParams,
|
|
900
|
+
})
|
|
901
|
+
|
|
902
|
+
// loading 结束和页码变化时滚动到顶部
|
|
903
|
+
watch([
|
|
904
|
+
() => props.loading,
|
|
905
|
+
() => props.currentPage,
|
|
906
|
+
], ([loading]) => {
|
|
907
|
+
if (loading) return;
|
|
908
|
+
tableDomRef.value.$el.querySelector('.el-table__body-wrapper').scrollTop = 0
|
|
836
909
|
})
|
|
837
910
|
|
|
838
911
|
</script>
|
|
@@ -11,24 +11,40 @@ export interface IColumnConfigRequired {
|
|
|
11
11
|
sortable?: boolean; // 该列是否允许排序,ture则表头弹窗会显示升降序按钮
|
|
12
12
|
slotName?: string; // 如果要自定义,传入 slotName
|
|
13
13
|
isAlwaysShow?: boolean; // 不可隐藏,显示设置中,该列不允许隐藏
|
|
14
|
-
|
|
14
|
+
/** 默认隐藏,显示设置中,该列默认隐藏 */
|
|
15
|
+
defaultHide?: boolean;
|
|
16
|
+
/** 列是否允许搜索,true则表头弹窗会多一个搜索框,一列中有多个搜索字段时传数组进行配置 */
|
|
17
|
+
search?: boolean | ISearchOptions
|
|
15
18
|
summary?: boolean; // 是否可以显示该列的统计
|
|
16
19
|
summaryMethod?: (values: any[]) => string | number; // 这一列的统计方法,values为该列的所有值
|
|
17
|
-
|
|
20
|
+
/** 过滤,传数组时默认复选框 */
|
|
21
|
+
filters?: {
|
|
22
|
+
type?: 'checkbox' | 'radio',
|
|
23
|
+
options: FiltersOption[]
|
|
24
|
+
default?: string | number | string[] | number[]
|
|
25
|
+
} | FiltersOption[]
|
|
18
26
|
// 透传el-table column有的属性, https://element.eleme.cn/#/en-US/component/table#table-column-attributes
|
|
19
27
|
[key: string]: any;
|
|
20
28
|
}
|
|
21
29
|
|
|
30
|
+
type FiltersOption = { value: string | number; text: string; [key: string]: any }
|
|
31
|
+
|
|
32
|
+
type ISearchOptions = {
|
|
33
|
+
prop: string,
|
|
34
|
+
label: string,
|
|
35
|
+
validator?: (value: string) => boolean
|
|
36
|
+
}[]
|
|
37
|
+
|
|
22
38
|
type IInputColumn = IColumnConfigRequired & {
|
|
23
39
|
inputType: string | number;
|
|
24
40
|
}
|
|
25
41
|
|
|
26
42
|
type ISelectColumn = IColumnConfigRequired & {
|
|
27
|
-
options: {key: string; value: string | number; [key: string]: any}[];
|
|
43
|
+
options: { key: string; value: string | number; [key: string]: any }[];
|
|
28
44
|
}
|
|
29
45
|
|
|
30
|
-
type IDateOnlyColumn = IColumnConfigRequired
|
|
31
|
-
type IDateTimeColumn = IColumnConfigRequired
|
|
46
|
+
type IDateOnlyColumn = IColumnConfigRequired
|
|
47
|
+
type IDateTimeColumn = IColumnConfigRequired
|
|
32
48
|
|
|
33
49
|
export type IColumnConfig = IInputColumn | ISelectColumn | IDateOnlyColumn | IDateTimeColumn
|
|
34
50
|
|
|
@@ -79,16 +95,22 @@ export interface IProps {
|
|
|
79
95
|
leftFixedCount?: number;
|
|
80
96
|
dragSemiRange?: number;
|
|
81
97
|
loading?: boolean;
|
|
98
|
+
settingStorgeKey?: string
|
|
99
|
+
localSort?: boolean
|
|
100
|
+
localFilter?: boolean
|
|
101
|
+
currentPage: number
|
|
82
102
|
}
|
|
83
103
|
|
|
84
104
|
export interface IEmits {
|
|
85
105
|
(e: 'selection-change', selection: any): void
|
|
86
|
-
(e: 'row-bg-change', param: {colorId: number; row: ITableDataItem; rowIndex: number}): void
|
|
87
|
-
(e: 'row-drag-drop', param: { row: any; fromIndex: number; toIndex: number; page: number; size: number;}): void
|
|
106
|
+
(e: 'row-bg-change', param: { colorId: number; row: ITableDataItem; rowIndex: number }): void
|
|
107
|
+
(e: 'row-drag-drop', param: { row: any; fromIndex: number; toIndex: number; page: number; size: number; }): void
|
|
88
108
|
(e: 'row-delete', param: { row: any; index: number; page: number; size: number; }): void
|
|
89
|
-
(e: 'row-edit', param: { row: any, index: number; page: number; size: number;}): void
|
|
90
|
-
(e: 'row-pin-to-top', param: { row: any, rawIndex: number; page: number; size: number;}): void
|
|
109
|
+
(e: 'row-edit', param: { row: any, index: number; page: number; size: number; }): void
|
|
110
|
+
(e: 'row-pin-to-top', param: { row: any, rawIndex: number; page: number; size: number; }): void
|
|
91
111
|
(e: 'row-edit-save', param: { page: number; size: number; row: any; changedData: Record<string, any>; }): void
|
|
92
|
-
(e: 'row-edit-cancel', param: { row: any; page: number; size: number;}): void
|
|
112
|
+
(e: 'row-edit-cancel', param: { row: any; page: number; size: number; }): void
|
|
93
113
|
(e: 'page-change', param: { page: number, size: number }): void
|
|
114
|
+
(e: 'search', param: Record<string, any>): void
|
|
115
|
+
(e: 'sort-change', param: { order: 'descending' | 'ascending' | null, prop: string }): void
|
|
94
116
|
}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import { computed, ref, watch, nextTick } from "vue"
|
|
2
|
-
import { IColumnConfig, IProps } from './types';
|
|
1
|
+
import { computed, ref, watch, nextTick, Ref } from "vue"
|
|
2
|
+
import { IColumnConfig, IEmits, IProps } from './types';
|
|
3
3
|
|
|
4
4
|
interface IUseColumnHeaderOperationParams {
|
|
5
5
|
props: IProps
|
|
6
6
|
tableDomRef: any
|
|
7
7
|
sortFilterPopoverRef: any
|
|
8
|
+
emit: IEmits;
|
|
9
|
+
showingColumns: Ref<string[]>
|
|
8
10
|
}
|
|
9
11
|
|
|
10
|
-
export default function useColumnHeaderOperation({props, tableDomRef, sortFilterPopoverRef}: IUseColumnHeaderOperationParams) {
|
|
12
|
+
export default function useColumnHeaderOperation({ props, tableDomRef, sortFilterPopoverRef, emit, showingColumns }: IUseColumnHeaderOperationParams) {
|
|
11
13
|
|
|
12
14
|
// column如果有sortable属性,点击列头部,会直接触发排序,为了在弹窗点确定时再触发排序,需要阻止点击立即排序
|
|
13
15
|
// 所以,初始渲染时,将sortable设置为false,在触发排序逻辑时再设置成真实的值,再利用el-table自身的排序逻辑触发排序
|
|
@@ -22,8 +24,8 @@ export default function useColumnHeaderOperation({props, tableDomRef, sortFilter
|
|
|
22
24
|
const tempSortingColumn = ref<IColumnConfig | null>(null);
|
|
23
25
|
|
|
24
26
|
// 生效中的过滤配置 和 临时过滤配置
|
|
25
|
-
const filteredValue = ref<Record<string, string[]>>({});
|
|
26
|
-
const tempFilteredValue = ref<Record<string, string[]>>({});
|
|
27
|
+
const filteredValue = ref<Record<string, string | number | number[] | string[]>>({});
|
|
28
|
+
const tempFilteredValue = ref<Record<string, string | number | number[] | string[]>>({});
|
|
27
29
|
|
|
28
30
|
// 生效中的统计配置 和 临时统计配置
|
|
29
31
|
const tempSummaryList = ref<string[]>([]);
|
|
@@ -33,14 +35,17 @@ export default function useColumnHeaderOperation({props, tableDomRef, sortFilter
|
|
|
33
35
|
const searchValue = ref<Record<string, string>>({});
|
|
34
36
|
const tempSearchValue = ref<Record<string, string>>({});
|
|
35
37
|
|
|
36
|
-
const isColumnFiltering = computed(() => Object.keys(tempFilteredValue.value).some(k =>
|
|
38
|
+
const isColumnFiltering = computed(() => Object.keys(tempFilteredValue.value).some(k => {
|
|
39
|
+
if (!Array.isArray(tempFilteredValue.value[k])) return tempFilteredValue.value[k]
|
|
40
|
+
return tempFilteredValue.value[k]?.length;
|
|
41
|
+
}));
|
|
37
42
|
|
|
38
|
-
const showColumnHeadSortIcon = (column: IColumnConfig) => column.filters || column.isColumnSortable || column.
|
|
43
|
+
const showColumnHeadSortIcon = (column: IColumnConfig) => column.filters || column.isColumnSortable || column.search || column.summary;
|
|
39
44
|
|
|
40
45
|
watch(
|
|
41
46
|
() => props.columnConfig,
|
|
42
47
|
(val) => {
|
|
43
|
-
filteredValue.value = val.reduce((prev, curr) => ({...prev, [curr.prop]: []}), {});
|
|
48
|
+
filteredValue.value = val.reduce((prev, curr) => ({ ...prev, [curr.prop]: [] }), {});
|
|
44
49
|
tempFilteredValue.value = { ...filteredValue.value };
|
|
45
50
|
},
|
|
46
51
|
{ immediate: true }
|
|
@@ -63,14 +68,24 @@ export default function useColumnHeaderOperation({props, tableDomRef, sortFilter
|
|
|
63
68
|
sums[index] = summaryMethod(values);
|
|
64
69
|
}
|
|
65
70
|
})
|
|
66
|
-
|
|
71
|
+
|
|
67
72
|
return sums
|
|
68
73
|
}
|
|
69
74
|
|
|
70
75
|
const isColumnHeadActive = (column: IColumnConfig) => {
|
|
71
|
-
return
|
|
76
|
+
return (
|
|
77
|
+
column.filters && (Array.isArray(column.filters)
|
|
78
|
+
? (filteredValue.value[column.prop] as any[]).length
|
|
79
|
+
: column.filters.type === 'radio'
|
|
80
|
+
? filteredValue.value[column.prop]
|
|
81
|
+
: (filteredValue.value[column.prop] as any[]).length)
|
|
82
|
+
) ||
|
|
83
|
+
(
|
|
84
|
+
column.search
|
|
85
|
+
? Array.isArray(column.search) && column.search?.some(v => searchValue.value[v.prop])
|
|
86
|
+
: searchValue.value[column.prop]
|
|
87
|
+
) ||
|
|
72
88
|
sortingColumn.value?.prop === column.prop ||
|
|
73
|
-
searchValue.value[column.prop] ||
|
|
74
89
|
summaryList.value.includes(column.prop);
|
|
75
90
|
}
|
|
76
91
|
|
|
@@ -82,7 +97,7 @@ export default function useColumnHeaderOperation({props, tableDomRef, sortFilter
|
|
|
82
97
|
tempSortType.value = sortType.value;
|
|
83
98
|
tempSortingColumn.value = sortingColumn.value ? { ...sortingColumn.value } as IColumnConfig : null;
|
|
84
99
|
// 临时合计项设置成实际的合计项
|
|
85
|
-
tempSummaryList.value = [
|
|
100
|
+
tempSummaryList.value = [...summaryList.value];
|
|
86
101
|
}
|
|
87
102
|
|
|
88
103
|
const closeSortAndFilterPopover = (exceptProp?: string) => {
|
|
@@ -98,21 +113,81 @@ export default function useColumnHeaderOperation({props, tableDomRef, sortFilter
|
|
|
98
113
|
tempSortingColumn.value = column;
|
|
99
114
|
}
|
|
100
115
|
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
116
|
+
const columnMap = computed(() => {
|
|
117
|
+
const obj: Record<string, IColumnConfig> = {}
|
|
118
|
+
props.columnConfig.forEach(column => {
|
|
119
|
+
obj[column.prop] = column
|
|
120
|
+
})
|
|
121
|
+
return obj
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
const emitSearch = () => {
|
|
125
|
+
const params: Record<string, any> = {};
|
|
126
|
+
// 仅提交显示的列的相关数据
|
|
127
|
+
showingColumns.value.forEach(prop => {
|
|
128
|
+
const column = columnMap.value[prop]
|
|
129
|
+
if (column.filters) {
|
|
130
|
+
params[prop] = filteredValue.value[prop]
|
|
131
|
+
}
|
|
132
|
+
if (column.search) {
|
|
133
|
+
if (Array.isArray(column.search)) {
|
|
134
|
+
column.search.forEach(v => {
|
|
135
|
+
params[v.prop] = searchValue.value[v.prop]
|
|
136
|
+
})
|
|
137
|
+
} else {
|
|
138
|
+
params[prop] = searchValue.value[prop]
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
Object.keys(params).forEach(key => {
|
|
144
|
+
if (params[key] === undefined) delete params[key]
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
emit('search', params);
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const handleHeaderOperationConfirm = async (column: IColumnConfig, scope) => {
|
|
151
|
+
if (column.search) {
|
|
152
|
+
// 校验
|
|
153
|
+
if (Array.isArray(column.search)) {
|
|
154
|
+
let validate = true;
|
|
155
|
+
column.search.forEach(v => {
|
|
156
|
+
if (!tempSearchValue.value[v.prop]) tempSearchValue.value[v.prop] = ''
|
|
157
|
+
if (!validate) return
|
|
158
|
+
if (v.validator) {
|
|
159
|
+
const result = v.validator(tempSearchValue.value[v.prop]);
|
|
160
|
+
if (validate && !result) validate = false;
|
|
161
|
+
}
|
|
162
|
+
})
|
|
163
|
+
// 校验未通过
|
|
164
|
+
if (!validate) return
|
|
165
|
+
} else {
|
|
166
|
+
if (!tempSearchValue.value[column.prop]) tempSearchValue.value[column.prop] = ''
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
summaryList.value = [...tempSummaryList.value];
|
|
171
|
+
sortingColumn.value = tempSortingColumn.value ? { ...tempSortingColumn.value } : null;
|
|
104
172
|
sortType.value = tempSortType.value;
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
173
|
+
|
|
174
|
+
if (sortingColumn.value) { // 确认时提交排序
|
|
175
|
+
if (props.localSort) {
|
|
176
|
+
// 恢复列配置的sortable属性,只有列配置的sortable为true,才能用下面的sort方法
|
|
177
|
+
inSorting.value = true;
|
|
178
|
+
await nextTick();
|
|
179
|
+
tableDomRef.value?.sort(sortingColumn.value.prop, sortType.value);
|
|
180
|
+
inSorting.value = false
|
|
181
|
+
} else {
|
|
182
|
+
emit('sort-change', { order: sortType.value, prop: sortingColumn.value.prop });
|
|
183
|
+
}
|
|
111
184
|
}
|
|
112
185
|
|
|
113
186
|
filteredValue.value = { ...tempFilteredValue.value };
|
|
114
187
|
searchValue.value = { ...tempSearchValue.value };
|
|
115
188
|
|
|
189
|
+
emitSearch();
|
|
190
|
+
|
|
116
191
|
filterColumns(scope.store);
|
|
117
192
|
|
|
118
193
|
closeSortAndFilterPopover();
|
|
@@ -120,18 +195,52 @@ export default function useColumnHeaderOperation({props, tableDomRef, sortFilter
|
|
|
120
195
|
tableDomRef.value?.doLayout();
|
|
121
196
|
}
|
|
122
197
|
|
|
123
|
-
const
|
|
124
|
-
|
|
198
|
+
const clearSort = () => {
|
|
199
|
+
sortingColumn.value = null;
|
|
200
|
+
sortType.value = null;
|
|
201
|
+
if (props.localSort) { // 前端过滤
|
|
125
202
|
tableDomRef.value?.clearSort();
|
|
126
|
-
|
|
127
|
-
|
|
203
|
+
} else { // 接口过滤
|
|
204
|
+
emit('sort-change', { order: null, prop: '' });
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const setSort = (params: { order: 'ascending' | 'descending', prop: string }) => {
|
|
209
|
+
const column = props.columnConfig.find(c => c.prop === params.prop);
|
|
210
|
+
if (column) {
|
|
211
|
+
sortingColumn.value = column;
|
|
212
|
+
sortType.value = params.order;
|
|
213
|
+
if (props.localSort) {
|
|
214
|
+
tableDomRef.value?.sort(params.prop, params.order);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const handleHeaderOperationReset = async (column: IColumnConfig, scope) => {
|
|
220
|
+
if (sortingColumn.value && sortingColumn.value.prop === column.prop) {
|
|
221
|
+
clearSort();
|
|
128
222
|
}
|
|
129
223
|
|
|
130
224
|
// 合计
|
|
131
225
|
summaryList.value = summaryList.value.filter(item => item !== column.prop);
|
|
132
226
|
|
|
133
|
-
|
|
134
|
-
|
|
227
|
+
if (column.filters) {
|
|
228
|
+
filteredValue.value[column.prop] = Array.isArray(column.filters)
|
|
229
|
+
? []
|
|
230
|
+
: column.filters.default ?? []
|
|
231
|
+
}
|
|
232
|
+
if (column.search) {
|
|
233
|
+
if (!Array.isArray(column.search)) {
|
|
234
|
+
searchValue.value[column.prop] = '';
|
|
235
|
+
} else {
|
|
236
|
+
column.search.forEach(v => {
|
|
237
|
+
searchValue.value[v.prop] = '';
|
|
238
|
+
})
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
emitSearch();
|
|
243
|
+
|
|
135
244
|
filterColumns(scope.store);
|
|
136
245
|
|
|
137
246
|
closeSortAndFilterPopover();
|
|
@@ -140,6 +249,7 @@ export default function useColumnHeaderOperation({props, tableDomRef, sortFilter
|
|
|
140
249
|
}
|
|
141
250
|
|
|
142
251
|
const filterColumns = (store) => {
|
|
252
|
+
if (!props.localFilter) return
|
|
143
253
|
store.states.columns.forEach(column => {
|
|
144
254
|
if (filteredValue.value[column.property]) {
|
|
145
255
|
store.commit('filterChange', {
|
|
@@ -165,7 +275,35 @@ export default function useColumnHeaderOperation({props, tableDomRef, sortFilter
|
|
|
165
275
|
store.states.data = data;
|
|
166
276
|
}
|
|
167
277
|
|
|
278
|
+
const setSearchParams = (params: Record<string, any>) => {
|
|
279
|
+
const _searchValue = {};
|
|
280
|
+
const _filteredValue = {};
|
|
281
|
+
|
|
282
|
+
// 设置搜索和过滤参数时,如果使用 showingColumns 遍历,会导致通过外部设置未显示的列的搜索和过滤参数丢失
|
|
283
|
+
props.columnConfig.forEach(column => {
|
|
284
|
+
if (column.search) {
|
|
285
|
+
if (Array.isArray(column.search)) {
|
|
286
|
+
column.search.forEach(v => {
|
|
287
|
+
_searchValue[v.prop] = params[v.prop];
|
|
288
|
+
});
|
|
289
|
+
} else {
|
|
290
|
+
_searchValue[column.prop] = params[column.prop] ?? '';
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
if (column.filters) {
|
|
294
|
+
const value = params[column.prop] ?? (Array.isArray(column.filters) ? [] : column.filters.default);
|
|
295
|
+
_filteredValue[column.prop] = value;
|
|
296
|
+
}
|
|
297
|
+
})
|
|
298
|
+
|
|
299
|
+
searchValue.value = { ...searchValue.value, ..._searchValue }
|
|
300
|
+
filteredValue.value = { ...filteredValue.value, ..._filteredValue }
|
|
301
|
+
}
|
|
302
|
+
|
|
168
303
|
return {
|
|
304
|
+
setSort,
|
|
305
|
+
clearSort,
|
|
306
|
+
setSearchParams,
|
|
169
307
|
isColumnHeadActive,
|
|
170
308
|
handleHeaderPopoverShow,
|
|
171
309
|
handleSort,
|
|
@@ -183,6 +321,6 @@ export default function useColumnHeaderOperation({props, tableDomRef, sortFilter
|
|
|
183
321
|
sortingColumn,
|
|
184
322
|
isColumnFiltering,
|
|
185
323
|
searchValue,
|
|
186
|
-
inSorting
|
|
324
|
+
inSorting,
|
|
187
325
|
}
|
|
188
326
|
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { Ref, ref } from "vue"
|
|
2
|
-
import { IEmits } from "./types"
|
|
2
|
+
import { IEmits, IProps } from "./types"
|
|
3
3
|
|
|
4
4
|
interface IParams {
|
|
5
5
|
emit: IEmits;
|
|
6
6
|
pageSize: Ref<number>;
|
|
7
|
-
|
|
7
|
+
props: IProps
|
|
8
8
|
tableDomRef: Ref<any>;
|
|
9
9
|
hasExpandRow: boolean
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
export default function useDefaultOperation({emit, pageSize,
|
|
12
|
+
export default function useDefaultOperation({ emit, pageSize, props, tableDomRef, hasExpandRow }: IParams) {
|
|
13
13
|
const operationPopoverRef = ref<any>(null);
|
|
14
14
|
const editingRowData = ref<Record<string, any>>({});
|
|
15
15
|
const editingRowIndex = ref<number>(-1);
|
|
@@ -18,7 +18,7 @@ export default function useDefaultOperation({emit, pageSize, currentPage, tableD
|
|
|
18
18
|
emit('row-delete', {
|
|
19
19
|
row,
|
|
20
20
|
index,
|
|
21
|
-
page: currentPage
|
|
21
|
+
page: props.currentPage,
|
|
22
22
|
size: pageSize.value
|
|
23
23
|
})
|
|
24
24
|
closeOperationPopover();
|
|
@@ -39,9 +39,9 @@ export default function useDefaultOperation({emit, pageSize, currentPage, tableD
|
|
|
39
39
|
// 折叠所有展开的行
|
|
40
40
|
closeAllExpandedRows();
|
|
41
41
|
const { row, $index: index } = scope;
|
|
42
|
-
editingRowData.value = {...row};
|
|
42
|
+
editingRowData.value = { ...row };
|
|
43
43
|
editingRowIndex.value = index;
|
|
44
|
-
emit('row-edit', { row, index, page: currentPage
|
|
44
|
+
emit('row-edit', { row, index, page: props.currentPage, size: pageSize.value });
|
|
45
45
|
closeOperationPopover();
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -52,9 +52,9 @@ export default function useDefaultOperation({emit, pageSize, currentPage, tableD
|
|
|
52
52
|
...dataList.slice(0, index),
|
|
53
53
|
...dataList.slice(index + 1)
|
|
54
54
|
];
|
|
55
|
-
newList.unshift({...row, isPinned: true});
|
|
55
|
+
newList.unshift({ ...row, isPinned: true });
|
|
56
56
|
store.states.data = newList;
|
|
57
|
-
emit('row-pin-to-top', { row, rawIndex: index, page: currentPage
|
|
57
|
+
emit('row-pin-to-top', { row, rawIndex: index, page: props.currentPage, size: pageSize.value });
|
|
58
58
|
closeOperationPopover();
|
|
59
59
|
}
|
|
60
60
|
|
|
@@ -68,7 +68,7 @@ export default function useDefaultOperation({emit, pageSize, currentPage, tableD
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
emit('row-edit-save', {
|
|
71
|
-
page: currentPage
|
|
71
|
+
page: props.currentPage,
|
|
72
72
|
size: pageSize.value,
|
|
73
73
|
row,
|
|
74
74
|
changedData
|
|
@@ -79,7 +79,7 @@ export default function useDefaultOperation({emit, pageSize, currentPage, tableD
|
|
|
79
79
|
const handleEditCancel = (row) => {
|
|
80
80
|
editingRowIndex.value = -1;
|
|
81
81
|
editingRowData.value = {};
|
|
82
|
-
emit('row-edit-cancel', { row, page: currentPage
|
|
82
|
+
emit('row-edit-cancel', { row, page: props.currentPage, size: pageSize.value });
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
return {
|
|
@@ -8,11 +8,10 @@ interface IUseDragSortParams {
|
|
|
8
8
|
viewSettingDragSortOptions: Ref<IColumnConfig[]>
|
|
9
9
|
beforeDragStart: () => boolean
|
|
10
10
|
currScope: Ref<any>
|
|
11
|
-
currentPage: Ref<number>
|
|
12
11
|
pageSize: Ref<number>
|
|
13
12
|
tableDomRef: Ref<any>
|
|
14
13
|
}
|
|
15
|
-
export default function useDragSort({props, emit, viewSettingDragSortOptions,
|
|
14
|
+
export default function useDragSort({ props, emit, viewSettingDragSortOptions, pageSize, beforeDragStart, currScope, tableDomRef }: IUseDragSortParams) {
|
|
16
15
|
|
|
17
16
|
const draggingData = ref<IDraggingData>({}); // 拖拽相关数据
|
|
18
17
|
const isMouseDown = ref(false);
|
|
@@ -21,7 +20,7 @@ export default function useDragSort({props, emit, viewSettingDragSortOptions, cu
|
|
|
21
20
|
const isOperating = ref(false);
|
|
22
21
|
|
|
23
22
|
onMounted(() => {
|
|
24
|
-
tableDomRef.value.$el.addEventListener('mousedown', () => {isOperating.value = true});
|
|
23
|
+
tableDomRef.value.$el.addEventListener('mousedown', () => { isOperating.value = true });
|
|
25
24
|
document.addEventListener('mousedown', handleDocumentMouseDown);
|
|
26
25
|
document.addEventListener('mousemove', handleDocumentMouseMove);
|
|
27
26
|
document.addEventListener('mouseup', handleDocumentMouseUp);
|
|
@@ -201,7 +200,7 @@ export default function useDragSort({props, emit, viewSettingDragSortOptions, cu
|
|
|
201
200
|
row: movedRow,
|
|
202
201
|
fromIndex: draggingIndex,
|
|
203
202
|
toIndex: dropIndex,
|
|
204
|
-
page: currentPage
|
|
203
|
+
page: props.currentPage,
|
|
205
204
|
size: pageSize.value
|
|
206
205
|
});
|
|
207
206
|
// 清理工作
|
|
@@ -210,7 +209,7 @@ export default function useDragSort({props, emit, viewSettingDragSortOptions, cu
|
|
|
210
209
|
|
|
211
210
|
const handleViewSettingDragMouseDown = (event, index) => {
|
|
212
211
|
const rowDoms = [...document.getElementsByClassName('view-setting-draggable-item')]
|
|
213
|
-
.reduce((pre, item, index) => ({...pre, [index]: [item]}), {});
|
|
212
|
+
.reduce((pre, item, index) => ({ ...pre, [index]: [item] }), {});
|
|
214
213
|
draggingData.value.isDragging = true;
|
|
215
214
|
draggingData.value.rowDoms = rowDoms;
|
|
216
215
|
draggingData.value.draggingIndex = +index;
|
|
@@ -6,29 +6,26 @@ interface IParams {
|
|
|
6
6
|
beforePageChange: () => void
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export default function usePagination({emit, beforePageChange}: IParams) {
|
|
9
|
+
export default function usePagination({ emit, beforePageChange }: IParams) {
|
|
10
10
|
|
|
11
11
|
const pageSize = ref(10);
|
|
12
|
-
const currentPage = ref(1);
|
|
13
12
|
|
|
14
13
|
const handlePageSizeChange = (size: number) => {
|
|
15
14
|
pageSize.value = size;
|
|
16
|
-
currentPage.value = 1;
|
|
17
15
|
// searchValue.value = {};
|
|
18
16
|
beforePageChange();
|
|
19
|
-
emit('page-change', {size, page:
|
|
17
|
+
emit('page-change', { size, page: 1 });
|
|
20
18
|
}
|
|
21
19
|
|
|
22
20
|
const handleCurrPageChange = (curr: number) => {
|
|
23
21
|
// searchValue.value = {};
|
|
24
22
|
beforePageChange();
|
|
25
|
-
emit('page-change', {size: pageSize.value, page: curr});
|
|
23
|
+
emit('page-change', { size: pageSize.value, page: curr });
|
|
26
24
|
}
|
|
27
25
|
|
|
28
26
|
return {
|
|
29
27
|
pageSize,
|
|
30
|
-
currentPage,
|
|
31
28
|
handlePageSizeChange,
|
|
32
|
-
handleCurrPageChange
|
|
29
|
+
handleCurrPageChange,
|
|
33
30
|
}
|
|
34
31
|
}
|
|
@@ -6,7 +6,7 @@ interface IUseRowBgColorParams {
|
|
|
6
6
|
emit: IEmits;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export default function useRowBgColor({colorList, emit}: IUseRowBgColorParams) {
|
|
9
|
+
export default function useRowBgColor({ colorList, emit }: IUseRowBgColorParams) {
|
|
10
10
|
const colorPopoverRef = ref<any>(null);
|
|
11
11
|
|
|
12
12
|
const isDefaultColor = (id: number) => {
|
|
@@ -31,11 +31,11 @@ export default function useRowBgColor({colorList, emit}: IUseRowBgColorParams) {
|
|
|
31
31
|
const handleColorChange = async (colorId: number, scope) => {
|
|
32
32
|
const { row, $index: rowIndex, store } = scope;
|
|
33
33
|
const dataList = store.states.data;
|
|
34
|
-
const curRow = {...dataList[rowIndex], colorId: +colorId};
|
|
34
|
+
const curRow = { ...dataList[rowIndex], colorId: +colorId };
|
|
35
35
|
const newList = [...dataList];
|
|
36
36
|
newList.splice(rowIndex, 1, curRow);
|
|
37
37
|
store.states.data = newList;
|
|
38
|
-
emit('row-bg-change', {colorId, row, rowIndex});
|
|
38
|
+
emit('row-bg-change', { colorId, row, rowIndex });
|
|
39
39
|
await nextTick();
|
|
40
40
|
// TODO: 为什么不是数组?为什么关闭弹窗不生效了?
|
|
41
41
|
colorPopoverRef.value?.doClose();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ref, nextTick, watch, ComputedRef, Ref, onMounted } from "vue"
|
|
1
|
+
import { ref, nextTick, watch, ComputedRef, Ref, onMounted, computed } from "vue"
|
|
2
2
|
import { IColumnConfig, IProps } from "./types"
|
|
3
3
|
|
|
4
4
|
interface IViewSettingParams {
|
|
@@ -13,12 +13,53 @@ export default function useViewSetting({ tableDomRef, showingColumns, actualColu
|
|
|
13
13
|
const columnsToBeShown = ref<string[]>([]); // 显示设置弹窗中勾选的列
|
|
14
14
|
const viewSettingVisible = ref(false);
|
|
15
15
|
const leftFixedColumnCount = ref(0);
|
|
16
|
+
const tempLeftFixedColumnCount = ref(0);
|
|
17
|
+
|
|
18
|
+
const storageKey = computed(() => `@lx-frontend/wrap-element-ui/table_setting_cloumns/${props.settingStorgeKey || (location.pathname === '/' ? location.hash : location.pathname)}`);
|
|
19
|
+
|
|
20
|
+
const saveSettingToStorge = () => localStorage.setItem(storageKey.value, JSON.stringify({
|
|
21
|
+
showingColumns: showingColumns.value,
|
|
22
|
+
leftFixedColumnCount: leftFixedColumnCount.value
|
|
23
|
+
}));
|
|
24
|
+
|
|
25
|
+
watch(
|
|
26
|
+
() => props.columnConfig,
|
|
27
|
+
(val) => {
|
|
28
|
+
const _keys = new Set(props.columnConfig.map(c => (c.prop)));
|
|
29
|
+
const _cache = localStorage.getItem(storageKey.value);
|
|
30
|
+
const setColumns = () => (showingColumns.value = val.filter(v => !v.defaultHide).map(c => c.prop));
|
|
31
|
+
if (!_cache) {
|
|
32
|
+
setColumns();
|
|
33
|
+
leftFixedColumnCount.value = props.leftFixedCount as number;
|
|
34
|
+
} else {
|
|
35
|
+
try {
|
|
36
|
+
// 缓存数据字段可能随着更新导致对不上,清理无效数据,防止出问题
|
|
37
|
+
const cache = JSON.parse(_cache);
|
|
38
|
+
if (!cache.showingColumns || !Array.isArray(cache.showingColumns)) {
|
|
39
|
+
setColumns();
|
|
40
|
+
} else {
|
|
41
|
+
showingColumns.value = cache.showingColumns.filter(key => _keys.has(key));
|
|
42
|
+
}
|
|
43
|
+
const _leftFixedColumnCount = Number(cache?.leftFixedColumnCount)
|
|
44
|
+
leftFixedColumnCount.value = isNaN(_leftFixedColumnCount) ? (props.leftFixedCount as number) : _leftFixedColumnCount;
|
|
45
|
+
// 写入清理后的数据
|
|
46
|
+
saveSettingToStorge();
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.error(error);
|
|
49
|
+
localStorage.removeItem(storageKey.value);
|
|
50
|
+
setColumns();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
{ immediate: true }
|
|
55
|
+
)
|
|
16
56
|
|
|
17
57
|
watch(
|
|
18
58
|
() => columnsToBeShown.value,
|
|
19
59
|
(val) => {
|
|
20
60
|
viewSettingDragSortOptions.value = props.columnConfig
|
|
21
61
|
.filter(c => val.includes(c.prop));
|
|
62
|
+
if (tempLeftFixedColumnCount.value > val.length) tempLeftFixedColumnCount.value = val.length
|
|
22
63
|
},
|
|
23
64
|
{ immediate: true }
|
|
24
65
|
)
|
|
@@ -39,6 +80,7 @@ export default function useViewSetting({ tableDomRef, showingColumns, actualColu
|
|
|
39
80
|
const handleViewSettingShow = () => {
|
|
40
81
|
viewSettingDragSortOptions.value = actualColumns.value
|
|
41
82
|
.filter(c => columnsToBeShown.value.includes(c.prop));
|
|
83
|
+
tempLeftFixedColumnCount.value = leftFixedColumnCount.value;
|
|
42
84
|
viewSettingVisible.value = true;
|
|
43
85
|
}
|
|
44
86
|
|
|
@@ -51,15 +93,25 @@ export default function useViewSetting({ tableDomRef, showingColumns, actualColu
|
|
|
51
93
|
const handleViewSettingConfirm = async () => {
|
|
52
94
|
viewSettingVisible.value = false;
|
|
53
95
|
showingColumns.value = viewSettingDragSortOptions.value.map(c => c.prop);
|
|
96
|
+
leftFixedColumnCount.value = tempLeftFixedColumnCount.value;
|
|
97
|
+
saveSettingToStorge()
|
|
54
98
|
await nextTick();
|
|
55
99
|
tableDomRef.value?.doLayout();
|
|
56
100
|
}
|
|
57
101
|
|
|
102
|
+
const handleInputTempLeftFixedColumnCount = (value: string) => {
|
|
103
|
+
const _value = Number(value)
|
|
104
|
+
if (isNaN(_value)) return
|
|
105
|
+
tempLeftFixedColumnCount.value = Math.max(0, Math.min(columnsToBeShown.value.length, Math.floor(_value)))
|
|
106
|
+
}
|
|
107
|
+
|
|
58
108
|
return {
|
|
59
109
|
viewSettingDragSortOptions,
|
|
60
110
|
columnsToBeShown,
|
|
61
111
|
viewSettingVisible,
|
|
62
112
|
leftFixedColumnCount,
|
|
113
|
+
tempLeftFixedColumnCount,
|
|
114
|
+
handleInputTempLeftFixedColumnCount,
|
|
63
115
|
handleViewSettingShow,
|
|
64
116
|
handleViewSettingClose,
|
|
65
117
|
handleViewSettingConfirm
|