@v2coding/ui 0.1.0

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 (49) hide show
  1. package/README.md +6 -0
  2. package/dist/v2coding-ui.esm.js +10840 -0
  3. package/dist/v2coding-ui.min.js +1 -0
  4. package/dist/v2coding-ui.ssr.js +10747 -0
  5. package/package.json +54 -0
  6. package/src/components/dialog/dialog.vue +179 -0
  7. package/src/components/drawer/drawer.vue +523 -0
  8. package/src/components/exports/index.vue +53 -0
  9. package/src/components/exports/remote-exports-dialog.vue +202 -0
  10. package/src/components/field/field.autocomplete.vue +21 -0
  11. package/src/components/field/field.calendar.vue +117 -0
  12. package/src/components/field/field.cascade.vue +233 -0
  13. package/src/components/field/field.checkbox.vue +134 -0
  14. package/src/components/field/field.color.vue +24 -0
  15. package/src/components/field/field.date.vue +145 -0
  16. package/src/components/field/field.icons.vue +123 -0
  17. package/src/components/field/field.number.vue +43 -0
  18. package/src/components/field/field.radio.vue +100 -0
  19. package/src/components/field/field.rate.vue +37 -0
  20. package/src/components/field/field.rich.vue +165 -0
  21. package/src/components/field/field.select.vue +210 -0
  22. package/src/components/field/field.slider.vue +66 -0
  23. package/src/components/field/field.switch.vue +14 -0
  24. package/src/components/field/field.text.vue +66 -0
  25. package/src/components/field/field.timepicker.vue +70 -0
  26. package/src/components/field/field.timeselect.vue +24 -0
  27. package/src/components/field/field.trigger.dialog.vue +50 -0
  28. package/src/components/field/field.trigger.popover.vue +63 -0
  29. package/src/components/field/field.upload.file.vue +241 -0
  30. package/src/components/field/field.upload.image.vue +125 -0
  31. package/src/components/field/field.upload.portrait.vue +304 -0
  32. package/src/components/fill-view/index.vue +43 -0
  33. package/src/components/form/form.dialog.vue +174 -0
  34. package/src/components/form/form.drawer.vue +246 -0
  35. package/src/components/form/form.fieldset.vue +110 -0
  36. package/src/components/form/form.item.vue +213 -0
  37. package/src/components/form/form.vue +293 -0
  38. package/src/components/head-menu/index.vue +188 -0
  39. package/src/components/head-menu/menu-item.vue +84 -0
  40. package/src/components/history/index.vue +360 -0
  41. package/src/components/icon/icon.vue +63 -0
  42. package/src/components/minimize/index.vue +342 -0
  43. package/src/components/page/page.vue +43 -0
  44. package/src/components/provider/provider.vue +15 -0
  45. package/src/components/scroll-view/scroll-view.vue +384 -0
  46. package/src/components/table/column.vue +262 -0
  47. package/src/components/table/table.pagination.vue +71 -0
  48. package/src/components/table/table.select.vue +165 -0
  49. package/src/components/table/table.vue +805 -0
@@ -0,0 +1,805 @@
1
+ <template>
2
+ <div class="ui-table" v-loading="realLoading">
3
+ <div class="ui-table-select-bar" v-show="hasSearchBar && searchBarVisible">
4
+ <slot name="search-bar"/>
5
+ </div>
6
+ <div class="ui-table-tool-bar" v-if="hasToolbar">
7
+ <slot name="tool-bar"/>
8
+ </div>
9
+ <div v-if="hasAlert" class="ui-table-alert">
10
+ <i class="el-icon-info"></i>
11
+ <slot name="alert">
12
+ 已选择 {{ selection.length }} 条.
13
+ <el-button type="text" @click="clearSelection">清空</el-button>
14
+ </slot>
15
+ </div>
16
+ <div style="position: relative;z-index: 1;">
17
+ <div v-if="privateTools && privateTools.length > 0" class="private-tools">
18
+ <div v-for="(tool, i) in privateTools" :key="i" class="tool">
19
+ <component :is="tool"></component>
20
+ </div>
21
+ </div>
22
+ </div>
23
+ <flex-scroll-view>
24
+ <el-table
25
+ ref="table"
26
+ height="100%"
27
+ :data="realData"
28
+ :border="border"
29
+ :class="tableCls"
30
+ v-bind="$attrs"
31
+ v-on="$listeners"
32
+ @selection-change="onSelectionChange"
33
+ @row-click="onRowClick"
34
+ @row-dblclick="onRowDblClick"
35
+ @cell-dblclick="onCellDbClick"
36
+ @select-all="onSelectAll"
37
+ @select="onSelect"
38
+ >
39
+ <slot></slot>
40
+ <component v-for="(column, i) in columns" :key="i" :is="column.componentName || 'ui-table-column'" v-bind="column" v-on="column.listeners"></component>
41
+ <template v-slot:empty>
42
+ <div class="ui-table-empty">暂无数据</div>
43
+ </template>
44
+ </el-table>
45
+ </flex-scroll-view>
46
+ <div v-show="hasPagination" class="footer-bar">
47
+ <slot name="footer-bar"/>
48
+ </div>
49
+ <remote-exports-dialog :visible.sync="exportsVisible" :current-page="remoteData && remoteData.no" :total-page="remoteData && remoteData.totalPages" v-bind-table:table @exports="onRemoteExports"/>
50
+ </div>
51
+ </template>
52
+ <script>
53
+ import ExportsMixin from '../exports/mixin';
54
+ import RemoteExportsDialog from '../exports/remote-exports-dialog';
55
+
56
+ let tableIdSeed = 1;
57
+
58
+ export default {
59
+ name: 'ui-table',
60
+ provide() {
61
+ return {
62
+ uiTable: this,
63
+ };
64
+ },
65
+ mixins: [ExportsMixin],
66
+ props: {
67
+ url: String,
68
+ data: Array,
69
+ params: {
70
+ type: Object,
71
+ default: () => ({}),
72
+ },
73
+ loading: Boolean,
74
+ searchBarInitVisible: {
75
+ type: Boolean,
76
+ default: true,
77
+ },
78
+ initLoad: {
79
+ type: Boolean,
80
+ default: true,
81
+ },
82
+ showButton: {
83
+ type: Boolean,
84
+ default: true,
85
+ },
86
+ alert: Boolean,
87
+ privateTools: {
88
+ type: Array,
89
+ default() {
90
+ // return ['refresh', 'columns'];
91
+ return ['columns'];
92
+ },
93
+ },
94
+ columns: Array,
95
+ border: {
96
+ type: Boolean,
97
+ default: false,
98
+ },
99
+ tableCls: String,
100
+ editValid: {
101
+ type: Function,
102
+ default: () => void 0,
103
+ },
104
+ editCellValid: {
105
+ type: Function,
106
+ default: () => void 0,
107
+ },
108
+ selectionMode: {
109
+ type: String,
110
+ validator: (val) => ['single', 'multiple'].includes(val),
111
+ default: 'single',
112
+ },
113
+ onSelect: {
114
+ type: Function,
115
+ default: () => void 0,
116
+ },
117
+ changeLoadedData: {
118
+ type: Function,
119
+ default: (res) => res,
120
+ },
121
+ rowSelect: {
122
+ type: Boolean,
123
+ default: true,
124
+ },
125
+ },
126
+ data() {
127
+ this.tablePageParams = {}; // tablePageParams 不用监听
128
+ return {
129
+ selection: [],
130
+ cols: [],
131
+ remoteData: null,
132
+ searchBar: null,
133
+ pagination: null,
134
+ remoteLoading: false,
135
+ exportsVisible: false,
136
+ searchBarVisible: this.searchBarInitVisible,
137
+ isTree: false, // 当前 table 是否含有 tree 列(用于: 含有 tree 时所有的列取消排序)
138
+ editData: null,
139
+ editPosition: null,
140
+ };
141
+ },
142
+ computed: {
143
+ hasSearchBar() {
144
+ return !!this.searchBar;
145
+ },
146
+ hasToolbar() {
147
+ if (this.showButton === false) {
148
+ return false;
149
+ }
150
+ return !!this.$scopedSlots['tool-bar'];
151
+ },
152
+ hasAlert() {
153
+ if (!this.alert) {
154
+ return false;
155
+ }
156
+ return !!this.cols.find((column) => column.type === 'selection');
157
+ },
158
+ hasPagination() {
159
+ return !!this.pagination;
160
+ },
161
+ realData() {
162
+ if (this.remoteData) {
163
+ if (this.hasPagination) {
164
+ return this.remoteData.data;
165
+ }
166
+ return this.remoteData;
167
+ }
168
+ return this.data;
169
+ },
170
+ realLoading() {
171
+ if (this.loading) {
172
+ return true;
173
+ }
174
+ return this.remoteLoading;
175
+ },
176
+ controlColumns() {
177
+ return this.cols.filter((column) => !['selection', 'action'].includes(column.type));
178
+ },
179
+ },
180
+ watch: {
181
+ url() {
182
+ this.reload();
183
+ },
184
+ params() {
185
+ this.reload();
186
+ },
187
+ async realData() {
188
+ await this.$nextTick();
189
+ setTimeout(() => {
190
+ this.doLayout();
191
+ }, 200);
192
+ },
193
+ },
194
+ created() {
195
+ this.uiTableId = 'ui-table_' + tableIdSeed++;
196
+ this.listeners = {
197
+ func: () => void 0,
198
+ register: (func) => {
199
+ this.listeners.func = func;
200
+ },
201
+ trigger: (...args) => {
202
+ this.listeners.func(...args);
203
+ },
204
+ };
205
+ },
206
+ mounted() {
207
+ this.init();
208
+ this.$root.$on('resize', this.onResize);
209
+ this.onResize();
210
+ },
211
+ beforeDestroy() {
212
+ this.$root.$off('resize', this.onResize);
213
+ },
214
+ methods: {
215
+ getExported() {
216
+ return {
217
+ // table methods
218
+ clearSelection: this.$refs.table.clearSelection,
219
+ toggleRowSelection: this.$refs.table.toggleRowSelection,
220
+ toggleAllSelection: this.$refs.table.toggleAllSelection,
221
+ toggleRowExpansion: this.$refs.table.toggleRowExpansion,
222
+ setCurrentRow: this.$refs.table.setCurrentRow,
223
+ clearSort: this.$refs.table.clearSort,
224
+ clearFilter: this.$refs.table.clearFilter,
225
+ doLayout: this.$refs.table.doLayout,
226
+ sort: this.$refs.table.sort,
227
+ // current component methods
228
+ reload: this.reload,
229
+ getSelection: this.getSelection,
230
+ getColumns: this.getColumns,
231
+ editRow: this.editRow,
232
+ };
233
+ },
234
+ init() {
235
+ if (this.hasSearchBar) {
236
+ // 在 searchBar 中执行加载数据方法
237
+ return;
238
+ }
239
+ this.initLoad && this.reload();
240
+ },
241
+ onResize() {
242
+ this.doLayout();
243
+ },
244
+ resetTableParams() {
245
+ this.initPaginationParams();
246
+ },
247
+ changePage(params = {}) {
248
+ this.tablePageParams = params;
249
+ this.reload();
250
+ },
251
+ reload(params) {
252
+ if (!this.url) {
253
+ return;
254
+ }
255
+ if (this.remoteLoading) {
256
+ return;
257
+ }
258
+ this.fetchData(params).then((res) => {
259
+ if (this.hasPagination) {
260
+ const { data, totalPages, no } = res;
261
+ if (Array.isArray(data) && data.length <= 0 && no !== 1) {
262
+ this.tablePageParams.no = totalPages;
263
+ this.reload(params);
264
+ return;
265
+ }
266
+ }
267
+ this.remoteData = this.changeLoadedData(res);
268
+ this.$emit('loaded', res);
269
+ });
270
+ },
271
+ getSelection() {
272
+ return this.selection;
273
+ },
274
+ getColumns() {
275
+ return this.$refs.table.columns.map(column => column.property).filter(Boolean);
276
+ },
277
+ getHeaders() {
278
+ const getAllHeaders = (columns, parents = []) => {
279
+ return columns.reduce((headers, column) => {
280
+ if (column.children) {
281
+ const _parents = [...parents];
282
+ column.label && _parents.push(column.label);
283
+ headers.push(...getAllHeaders(column.children, [..._parents]));
284
+ } else {
285
+ column.property && column.label && headers.push([...parents, column.label]);
286
+ }
287
+ return headers;
288
+ }, []);
289
+ };
290
+ return getAllHeaders(this.$refs.table.store.states.originColumns);
291
+ },
292
+ getSearchParams() {
293
+ if (this.searchBar) {
294
+ return this.searchBar.getSearchParams();
295
+ }
296
+ return {};
297
+ },
298
+ doLayout() {
299
+ this.$refs.table && this.$refs.table.doLayout();
300
+ },
301
+ setCurrentRow(row) {
302
+ this.$refs.table.setCurrentRow(row);
303
+ },
304
+ editRow(index) {
305
+ const editable = this.cols.some(col => col.editable);
306
+ if (!editable) {
307
+ return;
308
+ }
309
+ const rowData = this.$refs.table.tableData[index];
310
+ this.editData = JSON.parse(JSON.stringify(rowData));
311
+ this.editPosition = {
312
+ rowIndex: index,
313
+ };
314
+ },
315
+ /**
316
+ * @private
317
+ */
318
+ fetchData(params) {
319
+ this.remoteLoading = true;
320
+ const searchParams = this.getSearchParams();
321
+ return this.$axios.get(this.url, {
322
+ params: Object.assign({}, this.tablePageParams, searchParams, this.params, params || {}),
323
+ ...(this.hasPagination ? {} : {fallback: Array}), // list table 期望返回数组(网络请求错误时默认期望返回 Result)
324
+ }).then((r) => {
325
+ this.remoteLoading = false;
326
+ if (r.success) {
327
+ return Promise.resolve(r.data);
328
+ }
329
+ return Promise.resolve(this.hasPagination ? {no: 1, size: 0, data: [], total: 0, totalPages: 1} : []);
330
+ }).catch(() => {
331
+ this.remoteLoading = false;
332
+ return Promise.resolve(this.hasPagination ? {no: 1, size: 0, data: [], total: 0, totalPages: 1} : []);
333
+ });
334
+ },
335
+ /**
336
+ * @private
337
+ */
338
+ registerSearchBar(searchBar) {
339
+ this.searchBar = searchBar;
340
+ },
341
+ /**
342
+ * @private
343
+ */
344
+ registerPagination(pagination) {
345
+ this.pagination = pagination;
346
+ this.initPaginationParams();
347
+ },
348
+ /**
349
+ * @private
350
+ */
351
+ unRegisterPagination() {
352
+ this.removePaginationParams();
353
+ this.pagination = null;
354
+ },
355
+ /**
356
+ * @private
357
+ */
358
+ initPaginationParams() {
359
+ if (!this.pagination) {
360
+ return;
361
+ }
362
+ this.tablePageParams = this.pagination.getInitParams();
363
+ },
364
+ removePaginationParams() {
365
+ if (!this.pagination) {
366
+ return;
367
+ }
368
+ this.tablePageParams = {};
369
+ },
370
+ /**
371
+ * @private
372
+ */
373
+ clearSelection() {
374
+ this.$refs.table.clearSelection();
375
+ },
376
+ /**
377
+ * Events
378
+ */
379
+ toggleSearchBarVisible() {
380
+ this.searchBarVisible = !this.searchBarVisible;
381
+ },
382
+ toggleControlColumn(i) {
383
+ const column = this.controlColumns[i];
384
+ if (!column) {
385
+ return;
386
+ }
387
+ column.visible = !column.visible;
388
+ },
389
+ onSelectionChange(selection) {
390
+ let selects = selection;
391
+ if (this.selectionMode === 'single') {
392
+ const tableStoreStates = this.$refs.table.store.states;
393
+ const isAllSelected = tableStoreStates.isAllSelected;
394
+ const tableSelection = tableStoreStates.selection;
395
+ if (isAllSelected && (tableStoreStates.data || []).length === tableStoreStates.selection.length) {
396
+ selects = [];
397
+ selection.forEach(row => {
398
+ const i = tableSelection.indexOf(row);
399
+ i !== -1 && tableSelection.splice(i, 1);
400
+ this.$refs.table.toggleRowSelection(row, false);
401
+ });
402
+ } else {
403
+ selects = selection.slice(selection.length - 1, selection.length);
404
+ selection.slice(0, selection.length - 1).forEach(row => {
405
+ const i = tableSelection.indexOf(row);
406
+ i !== -1 && tableSelection.splice(i, 1);
407
+ this.$refs.table.toggleRowSelection(row, false);
408
+ });
409
+ }
410
+ }
411
+ this.selection = selects;
412
+ },
413
+ onRowClick(row) {
414
+ if (!this.rowSelect) {
415
+ return;
416
+ }
417
+ const currentRowIndex = this.$refs.table.tableData.indexOf(row);
418
+ if (this.editPosition && this.editPosition.rowIndex === currentRowIndex) {
419
+ return;
420
+ }
421
+ this.$refs.table.toggleRowSelection(row);
422
+ },
423
+ onRowDblClick(row) {
424
+ this.$emit('select-change', [row]);
425
+ },
426
+ onCellDbClick(row, column) {
427
+ const col = this.cols.find(c => c.columnId === column.id);
428
+ if (!col.editable) {
429
+ return;
430
+ }
431
+ const currentRowIndex = this.$refs.table.tableData.indexOf(row);
432
+ // row edit
433
+ if (this.editPosition && !this.editPosition.columnId && this.editPosition.rowIndex === currentRowIndex) {
434
+ return;
435
+ }
436
+ if (this.editPosition && this.editPosition.rowIndex === currentRowIndex && this.editPosition.columnId === column.id) {
437
+ return;
438
+ }
439
+ this.editPosition = {
440
+ rowIndex: currentRowIndex,
441
+ columnId: column.id,
442
+ prop: column.property,
443
+ };
444
+ this.editData = JSON.parse(JSON.stringify(row));
445
+ },
446
+ onSelectAll() {
447
+ if (this.selectionMode === 'single') {
448
+ this.$refs.table.clearSelection();
449
+ }
450
+ },
451
+ /**
452
+ * @private
453
+ */
454
+ addColumn(column) {
455
+ const isAdded = this.cols.some((c) => c.id === column.id);
456
+ if (isAdded) {
457
+ return;
458
+ }
459
+ this.cols.push(Object.freeze({
460
+ id: column.id,
461
+ type: column.type,
462
+ label: column.label,
463
+ visible: column.visible !== false,
464
+ editable: column.editable,
465
+ instance: column.instance,
466
+ columnId: '',
467
+ }));
468
+ if (column.type === 'tree') {
469
+ this.isTree = true;
470
+ }
471
+ },
472
+ removeColumn(columnId) {
473
+ const index = this.cols.findIndex((c) => c.id === columnId);
474
+ if (index === -1) {
475
+ return;
476
+ }
477
+ this.cols.splice(index, 1);
478
+ },
479
+ updateColumnId(id, columnId) {
480
+ const index = this.cols.findIndex((c) => c.id === id);
481
+ if (index === -1) {
482
+ return;
483
+ }
484
+ this.cols.splice(index, 1, Object.freeze({...this.cols[index], columnId}));
485
+ },
486
+ updateColumnVisible(id, visible) {
487
+ const index = this.cols.findIndex((c) => c.id === id);
488
+ if (index === -1) {
489
+ return;
490
+ }
491
+ this.cols.splice(index, 1, Object.freeze({...this.cols[index], visible}));
492
+ },
493
+ /**
494
+ * @private
495
+ */
496
+ getVisible(id) {
497
+ const column = this.cols.find((column) => column.id === id);
498
+ if (!column) {
499
+ return true;
500
+ }
501
+ return column.visible !== false;
502
+ },
503
+ getTableDom() {
504
+ const table = this.$el.querySelector('.el-table').cloneNode(true);
505
+ table.querySelector('.el-table__fixed').remove(); // 删除左边fixed
506
+ table.querySelector('.el-table__fixed-right').remove(); // 删除右边fixed
507
+ Array.from(table.querySelectorAll('.ui-table-column-action')).forEach(node => node.remove()); // 删除操作列
508
+ Array.from(table.querySelectorAll('.ui-table-column-selection')).forEach(node => node.remove()); // 删除选择列
509
+ return table;
510
+ },
511
+ cancelEdit() {
512
+ this.editData = null;
513
+ this.editPosition = null;
514
+ },
515
+ saveEdit() {
516
+ const valid = this.editValid(this.editData);
517
+ if (valid === false) {
518
+ return;
519
+ }
520
+ this.$emit('edit-row', this.editData);
521
+ this.$refs.table.tableData.splice(this.editPosition.rowIndex, 1, this.editData);
522
+ this.cancelEdit();
523
+ },
524
+ saveEditCell() {
525
+ const columnProp = this.editPosition.prop;
526
+ const originalValue = this.$refs.table.tableData[this.editPosition.rowIndex][columnProp];
527
+ const cellValue = this.editData[columnProp];
528
+ if (originalValue === cellValue) {
529
+ this.cancelEdit();
530
+ return;
531
+ }
532
+ const valid = this.editCellValid(cellValue, this.editData, columnProp);
533
+ if (valid === false) {
534
+ return;
535
+ }
536
+ this.$emit('edit-cell', cellValue, this.editData, columnProp);
537
+ this.$refs.table.tableData.splice(this.editPosition.rowIndex, 1, this.editData);
538
+ this.cancelEdit();
539
+ },
540
+ exportEntity(url = '', filename = '文件.xlsx') {
541
+ if (!url) {
542
+ console.error(`请指定 export api 请求地址`);
543
+ return;
544
+ }
545
+
546
+ const searchParams = this.getSearchParams();
547
+ const columns = this.getColumns();
548
+ const headers = this.getHeaders();
549
+ this.$axios.download(url, filename, {params: {...searchParams, columns: columns.join(','), headers: JSON.stringify(headers)}});
550
+ },
551
+ exportsLocal(filename) {
552
+ if (!this.$refs.table) {
553
+ return;
554
+ }
555
+ return this.exportsTable(filename, this.$refs.table);
556
+ },
557
+ exportsRemote(filename) {
558
+ this.exportsVisible = true;
559
+ this.listeners.register((params) => {
560
+ const {start, end, columns} = params;
561
+ const loading = this.$loading({
562
+ lock: true,
563
+ text: 'Loading',
564
+ spinner: 'el-icon-loading',
565
+ background: 'rgba(0, 0, 0, 0.7)',
566
+ });
567
+ const searchParams = this.getSearchParams();
568
+ const requestParams = {...searchParams, no: 1, size: end * this.tablePageParams.size};
569
+ this.$axios.get(this.url, {params: requestParams}).then(result => {
570
+ loading.close();
571
+ const {data = []} = result.data || {};
572
+ const list = data.slice((start - 1) * this.tablePageParams.size);
573
+ this.exports(list, filename, columns);
574
+ }).catch(() => {
575
+ loading.close();
576
+ this.$message.error('导出失败');
577
+ });
578
+ });
579
+ },
580
+ onRemoteExports(params) {
581
+ this.listeners.trigger(params);
582
+ },
583
+ // print() {
584
+ // this.$print(this.getTableDom());
585
+ // },
586
+ // excel() {
587
+ // const wb = XLSX.utils.table_to_book(this.getTableDom());
588
+ // const wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: true, type: 'array'});
589
+ // try {
590
+ // FileSaver.saveAs(new Blob([wbout], {type: 'application/octet-stream'}), 'sheetjs.xlsx');
591
+ // } catch (e) {
592
+ // console.error(e, wbout);
593
+ // }
594
+ // return wbout;
595
+ // },
596
+ },
597
+ components: {
598
+ RemoteExportsDialog,
599
+ Refresh: {
600
+ render(createElement) {
601
+ return createElement('el-tooltip', {props: {content: '刷新'}}, [
602
+ createElement('el-button', {
603
+ props: {icon: 'el-icon-fa-refresh', size: 'mini', circle: true},
604
+ on: {click: this.$parent.reload},
605
+ }),
606
+ ]);
607
+ },
608
+ },
609
+ Exports: {
610
+ render(createElement) {
611
+ return createElement('el-tooltip', {props: {content: '导出Excel'}}, [
612
+ createElement('el-button', {
613
+ props: {icon: 'el-icon-fa-cloud-download', size: 'mini', circle: true},
614
+ on: {click: this.$parent.exportsRemote},
615
+ }),
616
+ ]);
617
+ },
618
+ },
619
+ Columns: {
620
+ render(createElement) {
621
+ const {controlColumns, updateColumnVisible} = this.$parent;
622
+ // 非固定宽度列
623
+ const scalableColumns = controlColumns.filter(col => {
624
+ const colInstance = col.instance;
625
+ return !colInstance.realWidth && colInstance.minWidth && !colInstance.realFixed;
626
+ });
627
+ const visibleScalableColumns = scalableColumns.filter(c => c.visible);
628
+ let disabledColumn;
629
+ if (visibleScalableColumns.length <= 1) {
630
+ disabledColumn = visibleScalableColumns[0];
631
+ }
632
+ // 通过其它方式把 非固定宽度列 全部隐藏. 这里需要满足至少展示一个 非固定宽度列
633
+ if (visibleScalableColumns.length <= 0) {
634
+ const defaultVisibleColumn = scalableColumns[0]
635
+ defaultVisibleColumn && updateColumnVisible(defaultVisibleColumn.id, true);
636
+ }
637
+ return createElement('el-dropdown', {props: {trigger: 'click', hideOnClick: false}}, [
638
+ createElement('el-tooltip', {props: {content: '设置显示列'}}, [
639
+ createElement('el-button', {props: {icon: 'el-icon-more', circle: true, size: 'mini'}})
640
+ ]),
641
+ createElement('el-dropdown-menu', {slot: 'dropdown'}, controlColumns.map((column, i) => {
642
+ return createElement('el-dropdown-item', {key: i}, [
643
+ createElement('el-checkbox', {
644
+ props: {value: column.visible, disabled: column === disabledColumn},
645
+ on: {
646
+ input: () => {
647
+ updateColumnVisible(column.id, !column.visible);
648
+ this.$parent.$nextTick(() => {
649
+ this.$parent.doLayout();
650
+ });
651
+ },
652
+ },
653
+ }, [
654
+ createElement('span', {attrs: {class: 'column-label'}}, [column.label]),
655
+ ]),
656
+ ]);
657
+ })),
658
+ ]);
659
+ },
660
+ },
661
+ Search: {
662
+ render(createElement) {
663
+ if (!this.$parent.hasSearchBar) {
664
+ return null;
665
+ }
666
+ return createElement('el-tooltip', {props: {content: this.$parent.searchBarVisible ? '隐藏查询区域' : '显示查询区域'}}, [
667
+ createElement('el-button', {
668
+ props: {icon: 'el-icon-fa-search', circle: true},
669
+ on: {click: this.$parent.toggleSearchBarVisible},
670
+ }),
671
+ ]);
672
+ },
673
+ },
674
+ },
675
+ };
676
+ </script>
677
+ <style lang="less">
678
+ .ui-table {
679
+ flex: 1;
680
+ display: flex;
681
+ flex-direction: column;
682
+ z-index: 0;
683
+ background-color: #fff;
684
+ padding: 15px 20px;
685
+
686
+ .ui-table-select-bar {
687
+ flex: none;
688
+
689
+ .ui-table-select {
690
+ position: relative;
691
+ padding-right: 100px;
692
+
693
+ &.has-reset {
694
+ padding-right: 200px;
695
+ }
696
+
697
+ .submit-item {
698
+ position: absolute;
699
+ top: 0;
700
+ right: 0;
701
+ margin-right: 0;
702
+ margin-bottom: 0;
703
+ }
704
+ }
705
+
706
+ .el-input {
707
+ width: 200px;
708
+ }
709
+ }
710
+
711
+ .ui-table-tool-bar {
712
+ padding: 10px 0;
713
+ flex: none;
714
+ display: flex;
715
+ flex-wrap: wrap;
716
+ align-items: center;
717
+ flex-direction: row;
718
+ background-color: #fff;
719
+ }
720
+
721
+ .private-tools {
722
+ z-index: 1;
723
+ position: absolute;
724
+ top: 8px;
725
+ right: 5px;
726
+ display: flex;
727
+ flex-direction: row;
728
+ padding-left: 20px;
729
+
730
+ .tool + .tool {
731
+ margin-left: 5px;
732
+ }
733
+
734
+ .el-button.el-tooltip {
735
+ background: rgba(255, 255, 255, 0.6);
736
+ backdrop-filter: blur(3px);
737
+ box-shadow: 0 0 3px #999;
738
+ }
739
+ }
740
+
741
+ .ui-table-alert {
742
+ margin-bottom: 10px;
743
+ border: 1px solid #b3d8ff;
744
+ background-color: #ecf5ff;
745
+ border-radius: 3px;
746
+ padding: 8px 10px;
747
+
748
+ .el-icon-info {
749
+ color: #409eff;
750
+ margin-right: 6px;
751
+ }
752
+
753
+ .el-button--text {
754
+ padding: 0;
755
+ margin-left: 10px;
756
+ }
757
+ }
758
+
759
+ .el-table {
760
+ flex: 1;
761
+ border: 1px solid #EBEEF5;
762
+ border-bottom: none;
763
+ z-index: 0;
764
+ }
765
+
766
+ .footer-bar {
767
+ flex: none;
768
+ display: block;
769
+ padding: 20px 15px 15px;
770
+ background-color: #fff;
771
+
772
+ .el-pagination {
773
+ text-align: right;
774
+ padding: 0;
775
+ }
776
+ }
777
+
778
+ .ui-table-empty {
779
+ padding-top: 110px;
780
+ background: url("../../../assets/img/empty.svg") center top no-repeat;
781
+ background-size: auto 100px;
782
+ color: rgba(0, 0, 0, 0.65);
783
+ font-size: 14px;
784
+ line-height: 22px;
785
+ text-align: center;
786
+ }
787
+ }
788
+
789
+ .column-label {
790
+ width: 80px;
791
+ display: inline-block;
792
+ vertical-align: middle;
793
+ overflow: hidden;
794
+ text-overflow: ellipsis;
795
+ white-space: nowrap;
796
+ }
797
+
798
+ .ui-table-column-action {
799
+ .el-button {
800
+ box-shadow: none;
801
+ padding: 0;
802
+ line-height: inherit;
803
+ }
804
+ }
805
+ </style>