@lx-frontend/wrap-element-ui 0.4.6-beta.2 → 1.0.0-beta

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.
Files changed (73) hide show
  1. package/dist/AddMembers/index.vue.d.ts +31 -0
  2. package/dist/AuditSteps/index.vue.d.ts +46 -0
  3. package/dist/DemoComponent/index.vue.d.ts +2 -0
  4. package/dist/EditableTable/index.vue.d.ts +186 -0
  5. package/dist/EditableTable/types.d.ts +123 -0
  6. package/dist/EditableTable/useCellHover.d.ts +11 -0
  7. package/dist/EditableTable/useColumnHeaderOperation.d.ts +106 -0
  8. package/dist/EditableTable/useDefaultOperation.d.ts +22 -0
  9. package/dist/EditableTable/useDragSort.d.ts +15 -0
  10. package/dist/EditableTable/usePagination.d.ts +13 -0
  11. package/dist/EditableTable/useRowBgColor.d.ts +16 -0
  12. package/dist/EditableTable/useViewSetting.d.ts +58 -0
  13. package/dist/Ellipsis/MultilineEllipsis.vue.d.ts +91 -0
  14. package/dist/Ellipsis/index.vue.d.ts +89 -0
  15. package/dist/LxTable/index.vue.d.ts +2 -0
  16. package/dist/PopoverForm/index.vue.d.ts +50 -0
  17. package/dist/SearchForm/index.vue.d.ts +105 -0
  18. package/dist/SearchSelect/index.vue.d.ts +53 -0
  19. package/dist/index.css +1 -0
  20. package/dist/index.d.ts +11 -0
  21. package/dist/index.mjs +40808 -0
  22. package/dist/singleMessage/index.d.ts +4 -0
  23. package/package.json +60 -36
  24. package/{packages/AddMembers/src/AddMembers.vue → src/components/AddMembers/index.vue} +35 -13
  25. package/{packages/AuditSteps/src/AuditSteps.vue → src/components/AuditSteps/index.vue} +55 -0
  26. package/{packages/DemoComponent/src/DemoComponent.vue → src/components/DemoComponent/index.vue} +11 -0
  27. package/src/components/EditableTable/README.md +147 -0
  28. package/src/components/EditableTable/index.less +716 -0
  29. package/src/components/EditableTable/index.vue +842 -0
  30. package/src/components/EditableTable/pin-top.png +0 -0
  31. package/src/components/EditableTable/types.ts +94 -0
  32. package/src/components/EditableTable/useCellHover.ts +72 -0
  33. package/src/components/EditableTable/useColumnHeaderOperation.ts +188 -0
  34. package/src/components/EditableTable/useDefaultOperation.ts +96 -0
  35. package/src/components/EditableTable/useDragSort.ts +292 -0
  36. package/src/components/EditableTable/usePagination.ts +34 -0
  37. package/src/components/EditableTable/useRowBgColor.ts +51 -0
  38. package/src/components/EditableTable/useViewSetting.ts +67 -0
  39. package/{packages/Ellipsis/src → src/components/Ellipsis}/MultilineEllipsis.vue +1 -1
  40. package/{packages/Ellipsis/src/Ellipsis.vue → src/components/Ellipsis/index.vue} +5 -5
  41. package/src/components/LxTable/index.vue +296 -0
  42. package/{packages/SearchForm/src/SearchForm.vue → src/components/SearchForm/index.vue} +47 -21
  43. package/{packages/SearchSelect/src/SearchSelect.vue → src/components/SearchSelect/index.vue} +7 -4
  44. package/src/components/index.ts +22 -0
  45. package/babel.config.js +0 -5
  46. package/global.d.ts +0 -23
  47. package/packages/AddMembers/index.js +0 -11
  48. package/packages/AuditSteps/index.js +0 -7
  49. package/packages/DemoComponent/index.js +0 -7
  50. package/packages/Ellipsis/index.js +0 -7
  51. package/packages/LxTable/index.js +0 -11
  52. package/packages/LxTable/src/LxTable.vue +0 -296
  53. package/packages/PopoverForm/index.js +0 -7
  54. package/packages/SearchForm/index.js +0 -7
  55. package/packages/SearchSelect/index.js +0 -7
  56. package/packages/index.js +0 -59
  57. package/packages/theme-default/gulpfile.js +0 -25
  58. package/packages/theme-default/lib/AuditSteps.css +0 -1
  59. package/packages/theme-default/lib/DemoComponent.css +0 -1
  60. package/packages/theme-default/lib/index.css +0 -1
  61. package/packages/theme-default/package.json +0 -23
  62. package/packages/theme-default/src/AuditSteps.scss +0 -52
  63. package/packages/theme-default/src/DemoComponent.scss +0 -9
  64. package/packages/theme-default/src/common/var.scss +0 -0
  65. package/packages/theme-default/src/fonts/.gitkeep +0 -0
  66. package/packages/theme-default/src/index.css +0 -11
  67. package/packages/theme-default/src/index.scss +0 -2
  68. package/packages/utils/.gitkeep +0 -0
  69. package/plugins/wrap.js +0 -22
  70. package/postcss.config.js +0 -5
  71. package/tsconfig.json +0 -41
  72. /package/{packages/PopoverForm/src/PopoverForm.vue → src/components/PopoverForm/index.vue} +0 -0
  73. /package/{packages → src/components}/singleMessage/index.ts +0 -0
@@ -0,0 +1,842 @@
1
+ <template>
2
+ <div class="editable-table">
3
+ <div class="view-setting">
4
+ <div class="view-setting__btn-wrapper">
5
+ <div
6
+ class="view-setting__btn btn-pointer"
7
+ @click="handleViewSettingShow"
8
+ >
9
+ <i class="el-icon-setting" />
10
+ <div class="view-setting__btn-text">
11
+ 显示设置
12
+ </div>
13
+ </div>
14
+ </div>
15
+
16
+ <el-dialog
17
+ title="显示设置"
18
+ :visible.sync="viewSettingVisible"
19
+ width="750px"
20
+ :close-on-click-modal="false"
21
+ :append-to-body="true"
22
+ custom-class="view-setting__dialog"
23
+ >
24
+ <div class="view-setting__content">
25
+ <div class="view-setting__content-left">
26
+ <div class="view-setting__content-left-title">
27
+ 表头设置
28
+ </div>
29
+ <div class="view-setting__checkbox-wrapper">
30
+ <el-checkbox-group v-model="columnsToBeShown">
31
+ <el-checkbox
32
+ v-for="item in columnConfig"
33
+ :key="item.label"
34
+ :label="item.prop"
35
+ :disabled="item.isAlwaysShow"
36
+ >
37
+ <div class="view-setting__content-left-item">
38
+ {{ item.label }}
39
+ </div>
40
+ </el-checkbox>
41
+ </el-checkbox-group>
42
+ </div>
43
+ </div>
44
+ <div class="view-setting__content-right">
45
+ <div class="view-setting__content-right-title">
46
+ 已选择
47
+ <div class="view-setting__selected-count">
48
+ {{ columnsToBeShown.length }}
49
+ </div>
50
+ </div>
51
+ <div class="view-setting__content-right-frize">
52
+ 冻结前
53
+ <el-input
54
+ v-model="leftFixedColumnCount"
55
+ class="view-setting__content-right-input"
56
+ />
57
+
58
+ </div>
59
+ <div class="view-setting__content-right-selected">
60
+ <div
61
+ v-for="(item, index) in viewSettingDragSortOptions"
62
+ :key="item.prop"
63
+ class="view-setting__selected-item view-setting-draggable-item"
64
+ >
65
+ <div class="view-setting__selected-item-left">
66
+ <div
67
+ class="view-setting-drag-target view-setting__icon-wrapper"
68
+ :data-index="index"
69
+ >
70
+ <div
71
+ class="view-setting-drag-target editable-table-drag-icon"
72
+ :data-index="index"
73
+ />
74
+ </div>
75
+ <div class="view-setting__selected-item-name">
76
+ {{ item.label }}
77
+ </div>
78
+ </div>
79
+ <div
80
+ :class="['view-setting__selected-item-close', item.isAlwaysShow ? 'view-setting__selected-item-close--disabled' : '']"
81
+ @click="handleColumnClose(item)"
82
+ >
83
+ <i class="el-icon-close" />
84
+ </div>
85
+ </div>
86
+ </div>
87
+ </div>
88
+ </div>
89
+ <template #footer>
90
+ <el-button @click="handleViewSettingClose">
91
+ 取消
92
+ </el-button>
93
+ <el-button
94
+ type="primary"
95
+ @click="handleViewSettingConfirm"
96
+ >
97
+ 确认
98
+ </el-button>
99
+ </template>
100
+ </el-dialog>
101
+ </div>
102
+
103
+ <!-- 列表展示,属性透传,列编辑 -->
104
+ <el-table
105
+ ref="tableDomRef"
106
+ v-loading="loading"
107
+ :data="dataList"
108
+ :row-style="setRowStyle"
109
+ :row-class-name="setRowClassName"
110
+ :cell-class-name="setCellClassName"
111
+ :show-summary="summaryList.length > 0"
112
+ :summary-method="tableSummaryMethod"
113
+ v-bind="$attrs"
114
+ border
115
+ @selection-change="handleSelectionChange"
116
+ @cell-mouse-enter="debouncedHoverHandler"
117
+ @header-dragend="doTableLayout"
118
+ >
119
+ <el-table-column
120
+ v-if="rowDragAble"
121
+ width="30px"
122
+ class-name="editable-table__drag-cell no-inner-cell-border"
123
+ :fixed="leftFixedColumnCount > 0 ? 'left' : ''"
124
+ >
125
+ <template #default="scope">
126
+ <div
127
+ class="row-drag-target editable-table__drag-icon"
128
+ :data-index="scope.$index"
129
+ @mousedown="currScope = scope"
130
+ >
131
+ <div
132
+ :data-index="scope.$index"
133
+ class="row-drag-target editable-table-drag-icon"
134
+ />
135
+ </div>
136
+ </template>
137
+ </el-table-column>
138
+ <!-- 展开行 -->
139
+ <el-table-column
140
+ v-if="hasExpandRow"
141
+ width="30px"
142
+ type="expand"
143
+ :fixed="leftFixedColumnCount > 0 ? 'left' : ''"
144
+ class-name="no-inner-cell-border"
145
+ >
146
+ <template #default="scope">
147
+ <slot
148
+ name="expand"
149
+ v-bind="scope"
150
+ />
151
+ </template>
152
+ </el-table-column>
153
+ <!-- 选择列 -->
154
+ <el-table-column
155
+ v-if="hasSelectionColumn"
156
+ width="45px"
157
+ align="center"
158
+ type="selection"
159
+ :fixed="leftFixedColumnCount > 0 ? 'left' : ''"
160
+ class-name="no-inner-cell-border"
161
+ />
162
+ <!-- 编号列 -->
163
+ <el-table-column
164
+ v-if="hasIndexColumn"
165
+ min-width="30px"
166
+ type="index"
167
+ :fixed="leftFixedColumnCount > 0 ? 'left' : ''"
168
+ class-name="no-inner-cell-border"
169
+ />
170
+ <!-- 颜色选择列 -->
171
+ <el-table-column
172
+ v-if="colorList && colorList.length > 0"
173
+ width="22px"
174
+ class-name="editable-table__color-column no-inner-cell-border"
175
+ :fixed="leftFixedColumnCount > 0 ? 'left' : ''"
176
+ >
177
+ <template #header>
178
+ <div class="editable-table__color-icon" />
179
+ </template>
180
+ <template #default="scope">
181
+ <el-popover
182
+ ref="colorPopoverRef"
183
+ placement="right"
184
+ trigger="click"
185
+ popper-class="color-popover"
186
+ >
187
+ <div class="color-list">
188
+ <div
189
+ v-for="color in colorList"
190
+ :key="color.id"
191
+ class="color-list__item"
192
+ :style="{ backgroundColor: color.sampleColor }"
193
+ @click="handleColorChange(color.id, scope)"
194
+ >
195
+ <span :style="{color: color.textColor}">{{ color.name }}</span>
196
+ </div>
197
+ </div>
198
+ <template slot="reference">
199
+ <!-- 没有这个包裹的div标签,在拖动换行之后,无法调起颜色选择弹窗 -->
200
+ <div>
201
+ <div
202
+ v-if="isDefaultColor(scope.row.colorId)"
203
+ class="editable-table__color-icon"
204
+ />
205
+ <div
206
+ v-else
207
+ class="editable-table__selected-color"
208
+ :style="{ backgroundColor: getColorById(scope.row.colorId, 'sample') }"
209
+ />
210
+ </div>
211
+ </template>
212
+ </el-popover>
213
+ </template>
214
+ </el-table-column>
215
+ <!-- 这里的key很重要,必须保证每次生成的key都不一样,这样列排序功能才能生效,否则,即使actualColumns数组元素顺序发生变化,列顺序也不会改变。原因未知 -->
216
+ <el-table-column
217
+ v-for="(column, index) in actualColumns"
218
+ :key="column.prop + index"
219
+ resizable
220
+ class-name="editable-table__data-column"
221
+ :filtered-value="filteredValue[column.prop] || []"
222
+ v-bind="getColumnBindProps(column)"
223
+ >
224
+ <template
225
+ v-if="showColumnHeadSortIcon(column)"
226
+ #header="scope"
227
+ >
228
+ <el-popover
229
+ ref="sortFilterPopoverRef"
230
+ placement="bottom"
231
+ trigger="click"
232
+ popper-class="editable-table__sort-filter"
233
+ :data-prop="column.prop"
234
+ @show="handleHeaderPopoverShow(column)"
235
+ >
236
+ <template slot="reference">
237
+ <!-- 筛选中,或排序中,高亮 -->
238
+ <span :class="['editable-table__sort-reference', isColumnHeadActive(column) && 'editable-table__sort-reference--active']">
239
+ {{ column.label }}
240
+ <div :class="['editable-table__sort-icon', isColumnHeadActive(column) && 'editable-table__sort-icon--active']" />
241
+ </span>
242
+ </template>
243
+ <div class="sort-filter">
244
+ <div class="sort-filter__column-title">
245
+ {{ column.label }}
246
+ </div>
247
+ <div
248
+ v-if="column.isColumnSortable"
249
+ class="sort-filter__sort"
250
+ >
251
+ <div class="sort-filter__sort-title">
252
+ 排序
253
+ </div>
254
+ <div class="sort-filter__sort-btns">
255
+ <el-button
256
+ :class="['sort-filter__sort-btn', tempSortingColumn?.prop === column.prop && tempSortType === 'ascending' && 'sort-filter__sort-btn--active']"
257
+ @click="handleSort('ascending', column)"
258
+ >
259
+ 升序
260
+ </el-button>
261
+ <el-button
262
+ :class="['sort-filter__sort-btn', tempSortingColumn?.prop === column.prop && tempSortType === 'descending' && 'sort-filter__sort-btn--active']"
263
+ @click="handleSort('descending', column)"
264
+ >
265
+ 降序
266
+ </el-button>
267
+ </div>
268
+ </div>
269
+ <div
270
+ v-if="column.isColumnSearchAble"
271
+ class="sort-filter__search"
272
+ >
273
+ <div class="sort-filter__search-title">
274
+ 搜索
275
+ </div>
276
+ <el-input
277
+ v-model="tempSearchValue[column.prop]"
278
+ class="sort-filter__search-input"
279
+ placeholder="请输入内容"
280
+ />
281
+ </div>
282
+ <div
283
+ v-if="column.filters && column.filters.length > 0"
284
+ class="sort-filter__filter"
285
+ >
286
+ <div class="sort-filter__filter-title">
287
+ 筛选
288
+ </div>
289
+ <el-checkbox-group
290
+ v-model="tempFilteredValue[column.prop]"
291
+ class="sort-filter__filter-checkbox-group"
292
+ >
293
+ <el-checkbox
294
+ v-for="item in column.filters"
295
+ :key="item.value"
296
+ :label="item.value"
297
+ class="sort-filter__filter-checkbox"
298
+ >
299
+ <slot
300
+ :name="column.prop + '-filter-item'"
301
+ v-bind="item"
302
+ >
303
+ {{ item.text }}
304
+ </slot>
305
+ </el-checkbox>
306
+ </el-checkbox-group>
307
+ </div>
308
+ <div
309
+ v-if="column.summary"
310
+ class="sort-filter__filter"
311
+ >
312
+ <div class="sort-filter__filter-title">
313
+ 统计
314
+ </div>
315
+ <el-checkbox-group
316
+ v-model="tempSummaryList"
317
+ class="sort-filter__filter-checkbox-group"
318
+ >
319
+ <el-checkbox
320
+ :label="column.prop"
321
+ class="sort-filter__filter-checkbox"
322
+ >
323
+ <slot
324
+ :name="column.prop + '-summay-item'"
325
+ v-bind="column"
326
+ >
327
+ {{ column.label }}
328
+ </slot>
329
+ </el-checkbox>
330
+ </el-checkbox-group>
331
+ </div>
332
+ <div class="sort-filter__footer">
333
+ <el-button
334
+ class="sort-filter__reset-btn"
335
+ @click="handleHeaderOperationReset(column, scope)"
336
+ >
337
+ 重置
338
+ </el-button>
339
+ <el-button
340
+ class="sort-filter__confirm-btn"
341
+ type="primary"
342
+ @click="handleHeaderOperationConfirm(scope)"
343
+ >
344
+ 确定
345
+ </el-button>
346
+ </div>
347
+ </div>
348
+ </el-popover>
349
+ </template>
350
+ <!-- 默认操作按钮,defaultOperations属性不为空数组时展示。编辑状态下隐藏 -->
351
+ <template
352
+ v-if="column.prop === '$$operation'"
353
+ #default="scope"
354
+ >
355
+ <el-popover
356
+ v-if="editingRowIndex !== scope.$index"
357
+ ref="operationPopoverRef"
358
+ placement="bottom"
359
+ trigger="click"
360
+ popper-class="operation-popover"
361
+ >
362
+ <div
363
+ slot="reference"
364
+ class="operation-popover__operation-reference btn-pointer"
365
+ >
366
+ <el-button :class="['operation-popover__operation-btn', hoveringCellInfo.rowIndex === scope.$index && 'operation-popover__operation-btn--active']">
367
+ 操作
368
+ </el-button>
369
+ </div>
370
+ <div class="operation-popover__operation">
371
+ <div
372
+ v-if="defaultOperations.includes('delete')"
373
+ class="operation-popover__operation-item btn-pointer"
374
+ @click="handleDelete(scope.row, scope.$index)"
375
+ >
376
+ 删除
377
+ </div>
378
+ <div
379
+ v-if="defaultOperations.includes('edit')"
380
+ class="operation-popover__operation-item btn-pointer"
381
+ @click="handleEdit(scope)"
382
+ >
383
+ 编辑
384
+ </div>
385
+ <div
386
+ v-if="defaultOperations.includes('top')"
387
+ class="operation-popover__operation-item btn-pointer"
388
+ @click="handleRowPinToTop(scope)"
389
+ >
390
+ 置顶
391
+ </div>
392
+ <slot
393
+ name="custom-operation"
394
+ v-bind="scope"
395
+ />
396
+ </div>
397
+ </el-popover>
398
+ <div
399
+ v-else
400
+ class="operation-popover__save-cancel"
401
+ >
402
+ <div
403
+ class="btn-pointer operation-popover__btn"
404
+ @click="handleEditSave(scope.row)"
405
+ >
406
+ 保存
407
+ </div>
408
+ <div
409
+ class="btn-pointer operation-popover__btn"
410
+ @click="handleEditCancel(scope.row)"
411
+ >
412
+ 取消
413
+ </div>
414
+ </div>
415
+ </template>
416
+ <!-- 默认渲染、非编辑态,不需要特殊处理,el-table负责渲染 -->
417
+ <!-- 自定义插槽 -->
418
+ <template
419
+ v-else-if="column.slotName"
420
+ #default="scope"
421
+ >
422
+ <!-- 非编辑态 -->
423
+ <slot
424
+ v-if="scope.$index !== editingRowIndex"
425
+ v-bind="scope"
426
+ :name="column.slotName"
427
+ />
428
+ <!-- 编辑态 -->
429
+ <template v-else-if="scope.$index === editingRowIndex">
430
+ <!-- 自定义编辑 -->
431
+ <slot
432
+ v-if="column.editSlotName"
433
+ v-bind="{scope, column}"
434
+ :name="column.editSlotName"
435
+ />
436
+ <!-- 内置编辑类型 -->
437
+ <div v-else-if="column.editType">
438
+ <div v-if="column.editType === 'input'">
439
+ <el-input
440
+ v-model="editingRowData[column.prop]"
441
+ clearable
442
+ />
443
+ </div>
444
+ <div v-if="column.editType === 'select'">
445
+ <el-select v-model="editingRowData[column.prop]">
446
+ <el-option
447
+ v-for="item in column.selectOptions"
448
+ :key="item.label"
449
+ :label="item.label"
450
+ :value="item.value"
451
+ />
452
+ </el-select>
453
+ </div>
454
+ <el-date-picker
455
+ v-if="column.editType === 'date'"
456
+ v-model="editingRowData[column.prop]"
457
+ type="date"
458
+ placeholder="选择日期"
459
+ />
460
+ </div>
461
+ <!-- 不支持编辑 -->
462
+ <slot
463
+ v-else
464
+ v-bind="scope"
465
+ :name="column.slotName"
466
+ />
467
+ </template>
468
+ </template>
469
+ <!-- 默认渲染列,编辑态 -->
470
+ <template
471
+ v-else-if="editingRowIndex !== -1"
472
+ #default="scope"
473
+ >
474
+ <!-- 当前行编辑中,内置编辑类型 -->
475
+ <template v-if="editingRowIndex === scope.$index && column.editType">
476
+ <div v-if="column.editType === 'input'">
477
+ <el-input
478
+ v-model="editingRowData[column.prop]"
479
+ clearable
480
+ type="text"
481
+ />
482
+ </div>
483
+ <div v-if="column.editType === 'select'">
484
+ <el-select v-model="editingRowData[column.prop]">
485
+ <el-option
486
+ v-for="item in column.selectOptions"
487
+ :key="item.value"
488
+ :label="item.label"
489
+ :value="item.value"
490
+ />
491
+ </el-select>
492
+ </div>
493
+ <div v-if="column.editType === 'date'">
494
+ <el-date-picker
495
+ v-model="editingRowData[column.prop]"
496
+ type="date"
497
+ placeholder="选择日期"
498
+ />
499
+ </div>
500
+ </template>
501
+ <!-- 当前行编辑中,自定义编辑类型 -->
502
+ <slot
503
+ v-else-if="column.editSlotName && scope.$index === editingRowIndex"
504
+ v-bind="scope"
505
+ :name="column.editSlotName"
506
+ />
507
+ <!-- 当前行非编辑中 -->
508
+ <template v-else>
509
+ {{ column.formatter ? column.formatter(scope.row, column, scope.row[column.prop], scope.$index) : scope.row[column.prop] }}
510
+ </template>
511
+ </template>
512
+ <!-- hover状态渲染 -->
513
+ <template
514
+ v-else-if="column.hoverSlotName"
515
+ #default="scope"
516
+ >
517
+ <slot
518
+ v-if="scope.$index === hoveringCellInfo.rowIndex && column.prop === hoveringCellInfo.columnProperty"
519
+ v-bind="scope"
520
+ :name="column.hoverSlotName"
521
+ />
522
+ <slot
523
+ v-else-if="column.slotName"
524
+ v-bind="scope"
525
+ :name="column.slotName"
526
+ />
527
+ <template v-else>
528
+ {{ column.formatter ? column.formatter(scope.row, column, scope.row[column.prop], scope.$index) : scope.row[column.prop] }}
529
+ </template>
530
+ </template>
531
+ </el-table-column>
532
+ </el-table>
533
+ <div class="pagination-wrap">
534
+ <div>共{{ total }}项数据</div>
535
+ <el-pagination
536
+ background
537
+ layout="sizes, prev, pager, next, jumper"
538
+ :page-sizes="[10, 15, 30, 60, 100]"
539
+ :page-size.sync="pageSize"
540
+ :pager-count="11"
541
+ :current-page.sync="currentPage"
542
+ :total="total"
543
+ @size-change="handlePageSizeChange"
544
+ @current-change="handleCurrPageChange"
545
+ />
546
+ </div>
547
+ </div>
548
+ </template>
549
+
550
+ <script lang="ts" setup>
551
+ import { computed, nextTick, ref, watch } from 'vue';
552
+ import { Message } from 'element-ui'
553
+ import usePagination from './usePagination';
554
+ import useCellHover from './useCellHover';
555
+ import useViewSetting from './useViewSetting';
556
+ import useRowBgColor from './useRowBgColor';
557
+ import useDefaultOperation from './useDefaultOperation'
558
+ import useColumnHeaderOperation from './useColumnHeaderOperation';
559
+ import useDragSort from './useDragSort';
560
+ import { ITableDataItem, IColumnConfig, IDefaultOperationType, IColorList } from './types';
561
+
562
+ // defineProps泛型参数如果从外部传入,编译报错
563
+ interface IProps {
564
+ /** 表格数据 */
565
+ dataList: ITableDataItem[];
566
+ /** 列配置 */
567
+ columnConfig: IColumnConfig[];
568
+ /** 是否展示展开行 */
569
+ hasExpandRow?: boolean;
570
+ /** 是否展示序号 */
571
+ hasIndexColumn?: boolean;
572
+ /** 是否展示选择列 */
573
+ hasSelectionColumn?: boolean;
574
+ /** 是否支持行拖拽 */
575
+ rowDragAble?: boolean;
576
+ /** 表格总条数 */
577
+ total: number;
578
+ /** 自定义列操作,当前支持行编辑(edit),删除(delete),置顶(top) */
579
+ defaultOperations?: IDefaultOperationType[];
580
+ /** 行背景色列表 */
581
+ colorList?: IColorList;
582
+ /** 左侧固定列数 */
583
+ leftFixedCount?: number;
584
+ /** 性能优化参数,调整拖拽的范围 */
585
+ dragSemiRange?: number;
586
+ /** 是否显示加载 */
587
+ loading?: boolean;
588
+ }
589
+
590
+ interface IEmits {
591
+ /** 行选中 */
592
+ (e: 'selection-change', selection: any): void
593
+ /** 修改行背景色 */
594
+ (e: 'row-bg-change', param: {colorId: number; row: ITableDataItem; rowIndex: number}): void
595
+ /** 行拖拽放置事件 */
596
+ (e: 'row-drag-drop', param: { row: any; fromIndex: number; toIndex: number; page: number; size: number;}): void
597
+ /** 行删除 */
598
+ (e: 'row-delete', param: { row: any; index: number; page: number; size: number; }): void
599
+ /** 点击编辑按钮立即触发 */
600
+ (e: 'row-edit', param: { row: any, index: number; page: number; size: number;}): void
601
+ /** 行置顶 */
602
+ (e: 'row-pin-to-top', param: { row: any, rawIndex: number; page: number; size: number;}): void
603
+ /** 行编辑保存 */
604
+ (e: 'row-edit-save', param: { page: number; size: number; row: any; changedData: Record<string, any>; }): void
605
+ /** 行编辑取消 */
606
+ (e: 'row-edit-cancel', param: { row: any; page: number; size: number;}): void
607
+ /** 页码改变 */
608
+ (e: 'page-change', param: { page: number, size: number }): void
609
+ }
610
+
611
+ const props = withDefaults(defineProps<IProps>(), {
612
+ dataList: () => [],
613
+ columnConfig: () => [],
614
+ hasExpandRow: false,
615
+ hasIndexColumn: false,
616
+ hasSelectionColumn: false,
617
+ rowDragAble: false,
618
+ total: 0,
619
+ defaultOperations: () => [],
620
+ colorList: () => [],
621
+ leftFixedCount: 1,
622
+ dragSemiRange: 15,
623
+ loading: false
624
+ })
625
+
626
+ // 同defineProps一样,不支持泛型参数从外部导入
627
+ const emit = defineEmits<IEmits>()
628
+
629
+ const showingColumns = ref<string[]>([]); // 表格中实际展示的列
630
+
631
+ const actualColumns = computed(() => {
632
+ const res: IColumnConfig[] = [];
633
+ let cnt = leftFixedColumnCount.value
634
+
635
+ // 列排序和列过滤
636
+ for (const prop of showingColumns.value) {
637
+ const rawItem = props.columnConfig.find(c => c.prop === prop) ?? {} as IColumnConfig;
638
+ const item: IColumnConfig = {
639
+ ...rawItem,
640
+ isColumnSortable: rawItem.sortable,
641
+ sortable: inSorting.value ? rawItem.sortable : false
642
+ };
643
+ if (item) {
644
+ if (cnt > 0) {
645
+ item.fixed = 'left';
646
+ // eslint-disable-next-line no-plusplus
647
+ cnt--;
648
+ } else {
649
+ item.fixed = undefined;
650
+ }
651
+ res.push(item);
652
+ }
653
+ }
654
+
655
+ // 使用默认操作项,添加默认操作列。该列在编辑模式下隐藏
656
+ if (props.defaultOperations && props.defaultOperations.length > 0) {
657
+ res.push({
658
+ label: '操作',
659
+ prop: '$$operation',
660
+ 'min-width': '100px',
661
+ fixed: 'right'
662
+ });
663
+ }
664
+
665
+ return res;
666
+ })
667
+
668
+ const sortFilterPopoverRef = ref<any>(null);
669
+ const tableDomRef = ref<any>(null);
670
+ const currScope = ref<any>(null);
671
+
672
+ /************ 分页相关 *************/
673
+ const beforePageChange = () => {
674
+ searchValue.value = {};
675
+ }
676
+ const {
677
+ pageSize,
678
+ currentPage,
679
+ handleCurrPageChange,
680
+ handlePageSizeChange
681
+ } = usePagination({
682
+ emit,
683
+ beforePageChange
684
+ })
685
+
686
+ /************ 表格单元格hover事件相关 ************ */
687
+ const {
688
+ hoveringCellInfo,
689
+ setCellClassName,
690
+ debouncedHoverHandler
691
+ } = useCellHover(tableDomRef)
692
+
693
+ /************ 行背景色设置相关 ************ */
694
+ const {
695
+ isDefaultColor,
696
+ getColorById,
697
+ setRowStyle,
698
+ handleColorChange,
699
+ colorPopoverRef
700
+ } = useRowBgColor({
701
+ colorList: props.colorList,
702
+ emit
703
+ })
704
+
705
+ /************ 默认的操作相关 ************ */
706
+ const {
707
+ operationPopoverRef,
708
+ editingRowData,
709
+ editingRowIndex,
710
+ handleDelete,
711
+ handleEdit,
712
+ handleEditSave,
713
+ handleEditCancel,
714
+ handleRowPinToTop,
715
+ closeAllExpandedRows
716
+ } = useDefaultOperation({
717
+ emit,
718
+ tableDomRef,
719
+ pageSize,
720
+ currentPage,
721
+ hasExpandRow: props.hasExpandRow
722
+ })
723
+
724
+ /************ 显示设置相关 ************ */
725
+ const {
726
+ viewSettingDragSortOptions,
727
+ columnsToBeShown,
728
+ viewSettingVisible,
729
+ leftFixedColumnCount,
730
+ handleViewSettingShow,
731
+ handleViewSettingClose,
732
+ handleViewSettingConfirm
733
+ } = useViewSetting({
734
+ tableDomRef,
735
+ showingColumns,
736
+ actualColumns,
737
+ props
738
+ })
739
+
740
+ /************ 列头部操作相关 ************ */
741
+ const {
742
+ isColumnHeadActive,
743
+ handleSort,
744
+ handleHeaderPopoverShow,
745
+ handleHeaderOperationConfirm,
746
+ handleHeaderOperationReset,
747
+ summaryList,
748
+ tableSummaryMethod,
749
+ filteredValue,
750
+ showColumnHeadSortIcon,
751
+ tempSortingColumn,
752
+ tempSearchValue,
753
+ tempFilteredValue,
754
+ tempSummaryList,
755
+ tempSortType,
756
+ sortingColumn,
757
+ isColumnFiltering,
758
+ searchValue,
759
+ inSorting
760
+ } = useColumnHeaderOperation({
761
+ tableDomRef,
762
+ sortFilterPopoverRef,
763
+ props
764
+ })
765
+
766
+ /************ 表格行拖拽和显示设置列拖拽 ************ */
767
+ const beforeDragStart = () => {
768
+ // 如果有列存在排序,不允许拖拽
769
+ if (sortingColumn.value) {
770
+ Message.warning('已有列正在排序,不允许拖拽。');
771
+ return false;
772
+ }
773
+
774
+ // 如果有列存在筛选,不允许拖拽
775
+ if (isColumnFiltering.value) {
776
+ Message.warning('已有列正在筛选,不允许拖拽。');
777
+ return false;
778
+ }
779
+
780
+ editingRowIndex.value = -1; // 关闭编辑状态
781
+
782
+ return true
783
+ }
784
+
785
+ useDragSort({
786
+ emit,
787
+ props,
788
+ viewSettingDragSortOptions,
789
+ beforeDragStart,
790
+ currentPage,
791
+ pageSize,
792
+ currScope,
793
+ tableDomRef,
794
+ })
795
+
796
+ const doTableLayout = async () => {
797
+ await nextTick();
798
+ tableDomRef.value?.doLayout();
799
+ }
800
+
801
+ watch(
802
+ () => props.columnConfig,
803
+ (val) => {
804
+ showingColumns.value = val.map(c => c.prop);
805
+ },
806
+ { immediate: true }
807
+ )
808
+
809
+ // 过滤出自定义属性,将其它属性全部透传给 el-table-column
810
+ const getColumnBindProps = (column: IColumnConfig) => {
811
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
812
+ const { editAble, editType, slotName, inputType, options, ...rest } = column;
813
+ return rest;
814
+ }
815
+
816
+ const setRowClassName = (scope) => {
817
+ return `
818
+ custom-row-classname
819
+ custom-row-classname-${scope.rowIndex}
820
+ ${scope.row.isPinned ? 'custom-row-classname-pinned' : ''}
821
+ `
822
+ }
823
+
824
+ const handleSelectionChange = (e) => {
825
+ emit('selection-change', e);
826
+ }
827
+
828
+ const handleColumnClose = (item) => {
829
+ if (item.isAlwaysShow) return;
830
+ columnsToBeShown.value = columnsToBeShown.value.filter(c => c !== item.prop);
831
+ }
832
+
833
+ defineExpose({
834
+ closeAllExpandedRows,
835
+ elTableRef: tableDomRef
836
+ })
837
+
838
+ </script>
839
+
840
+ <style lang="less">
841
+ @import './index.less';
842
+ </style>