n20-common-lib 3.0.37 → 3.0.39

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 (40) hide show
  1. package/package.json +2 -2
  2. package/src/assets/css/_coreLib.scss +4 -1
  3. package/src/assets/css/button.scss +8 -19
  4. package/src/assets/css/element-variables.scss +11 -11
  5. package/src/assets/css/file-upload-table.scss +10 -0
  6. package/src/assets/css/layout-content.scss +1 -0
  7. package/src/{components/PageHeader/style.scss → assets/css/page-header.scss} +22 -7
  8. package/src/assets/css/page.scss +12 -0
  9. package/src/assets/css/pagination.scss +76 -17
  10. package/src/assets/css/rootvar.scss +1 -0
  11. package/src/assets/css/secondary-tab.scss +60 -43
  12. package/src/assets/css/table.scss +165 -19
  13. package/src/assets/css/tabs.scss +68 -0
  14. package/src/components/FileUploadTable/FileUploadTableV3.vue +2 -2
  15. package/src/components/FileUploadTable/aiCheckDialog.vue +2 -2
  16. package/src/components/PageHeader/index.vue +11 -6
  17. package/src/components/PageLayout/page.vue +15 -3
  18. package/src/components/Pagination/index.vue +7 -4
  19. package/src/components/Pagination/main.vue +113 -0
  20. package/src/components/SecondaryTab/index.vue +45 -34
  21. package/src/components/ShowColumn/index.vue +14 -4
  22. package/src/components/TableOperate/index.vue +124 -0
  23. package/src/components/TablePro/index.vue +185 -97
  24. package/src/components/TableSetSize/index.vue +3 -3
  25. package/src/components/TableSetSize/index1.vue +82 -0
  26. package/src/components/Tabs/index.vue +64 -0
  27. package/src/index.js +4 -1
  28. package/src/utils/asciiWidth.js +1 -1
  29. package/src/utils/axios.js +1 -1
  30. package/style/index.css +1 -1
  31. package/theme/blue.css +1 -1
  32. package/theme/cctcRed.css +1 -1
  33. package/theme/green.css +1 -1
  34. package/theme/lightBlue.css +1 -1
  35. package/theme/orange.css +1 -1
  36. package/theme/purple.css +1 -1
  37. package/theme/red.css +1 -1
  38. package/theme/yellow.css +1 -1
  39. package/src/components/TableSetSize/index copy.vue +0 -69
  40. package/src/components/TableSetSize/style.scss +0 -81
@@ -7,6 +7,7 @@
7
7
  <div class="skeleton-cell" v-for="col in skeletonCols" :key="'col-' + col"></div>
8
8
  </div>
9
9
  </div>
10
+ <!-- 表格 -->
10
11
  <vxe-table
11
12
  ref="vxeTable"
12
13
  :key="colsKey"
@@ -48,7 +49,8 @@
48
49
  iconMatch: 'n20-icon-xiala-moren'
49
50
  }"
50
51
  :merge-cells="mergeCells"
51
- v-bind="Object.assign({ size: size }, $attrs, sizeBind)"
52
+ :row-class-name="getRowClassName"
53
+ v-bind="{ size, ...$attrs, ...sizeBind }"
52
54
  v-on="$listeners"
53
55
  @sort-change="(val) => customSortMethod(val)"
54
56
  @filter-change="filterChange"
@@ -58,6 +60,7 @@
58
60
  @cell-mouseleave="handleCellMouseLeave"
59
61
  @scroll="handleTableScroll"
60
62
  @toggle-tree-expand="syncExpandState"
63
+ @column-resizable-change="resizableChange"
61
64
  >
62
65
  <template v-for="(item, i) in _columns">
63
66
  <slot v-if="item.slotName" :name="item.slotName" :column="item"></slot>
@@ -201,45 +204,47 @@
201
204
  ></i>
202
205
  </div>
203
206
  </template>
204
- <template #default="{ row }">
205
- <slot :name="`cell_${item.prop}`" :row="row">{{ row[item.prop] }}</slot>
207
+ <!-- 处理旧格式 formatter 和 render -->
208
+ <template v-if="item._oldFormatter || item._oldRender" #default="{ row, column }">
209
+ <!-- 旧的 render 函数 -->
210
+ <template v-if="item._oldRender && item.render">
211
+ <vxe-tooltip :content="row[column.property]">
212
+ <template #default>
213
+ <div v-html="item.render($createElement, row)"></div>
214
+ </template>
215
+ </vxe-tooltip>
216
+ </template>
217
+ <!-- 旧的 formatter 函数:formatter: ({ row }) => html -->
218
+ <template v-else-if="item._oldFormatter && item._originalFormatter">
219
+ <div v-html="item._originalFormatter({ row })"></div>
220
+ </template>
221
+ <!-- 纯对象字段 -->
222
+ <template
223
+ v-else-if="row[column.property] && typeof row[column.property] === 'object' && row[column.property].name"
224
+ >
225
+ {{ row[column.property].name }}
226
+ </template>
227
+ <slot v-else :name="`cell_${item.prop}`" :row="row">{{ row[column.property] }}</slot>
206
228
  </template>
207
229
  </vxe-column>
208
230
  </template>
209
- <vxe-column fixed="right" header-class-name="fixed-column__static" :min-width="clacStaticColumnWidth">
210
- <template #header>
211
- <div class="flex-box flex-v flex-c">
212
- <i
213
- v-if="showColumn"
214
- v-title="$lc('设置显示列')"
215
- class="v3-icon-system-solution pointer"
216
- :class="hoverIconKey === 'showColumn' ? 'color-primary' : ''"
217
- @mouseenter="hoverIconKey = 'showColumn'"
218
- @mouseleave="hoverIconKey = null"
219
- @click="$emit('visible-column')"
220
- ></i>
221
- <tableSetSize v-if="showSetsize" :size="sizeC" v-bind="$attrs" @update:size="sizeUp" @resize="sizeSet" />
222
- <i
223
- v-if="$attrs.treeConfig || $attrs['tree-config']"
224
- v-title="!isExpand ? $lc('展开分组') : $lc('折叠分组')"
225
- class="pointer"
226
- :class="[
227
- isExpand ? 'v3-icon-group-collapse' : 'v3-icon-group-expand',
228
- hoverIconKey === 'toggleExpand' ? 'color-primary' : ''
229
- ]"
230
- @mouseenter="hoverIconKey = 'toggleExpand'"
231
- @mouseleave="hoverIconKey = null"
232
- @click="toggleExpand"
233
- ></i>
234
- </div>
235
- </template>
236
- </vxe-column>
237
231
  <template #empty>
238
232
  <slot name="empty">
239
233
  <empty type="noData" :content="$lc('暂无数据')" :height="200" :width="200" />
240
234
  </slot>
241
235
  </template>
242
236
  </vxe-table>
237
+ <!-- 操作列 -->
238
+ <tableOperate
239
+ :showColumn="showColumn"
240
+ :showSetsize="showSetsize"
241
+ :size="sizeC"
242
+ v-bind="$attrs"
243
+ @update:size="sizeUp"
244
+ @resize="sizeSet"
245
+ @toggle-expand="toggleExpand"
246
+ @visible-column="dialogVisible = !dialogVisible"
247
+ />
243
248
  <!-- 操作列的悬浮按钮组 -->
244
249
  <transition name="hover-btns-fade">
245
250
  <div
@@ -288,12 +293,29 @@
288
293
  </div>
289
294
  </div>
290
295
  </transition>
296
+
297
+ <table-show-column
298
+ ref="showColumn"
299
+ :dialog-visible.sync="dialogVisible"
300
+ :check-columns="checkColumns"
301
+ :columns="columns"
302
+ :label-key="labelKey"
303
+ :auto-save="autoSave"
304
+ :page-id="pageId"
305
+ :isExport="isExport"
306
+ :isFilter="isFilter"
307
+ :width="width"
308
+ :hasPX="hasPX"
309
+ @setColumns="setColumns"
310
+ />
291
311
  </div>
292
312
  </template>
293
313
 
294
314
  <script>
295
315
  import empty from '../Empty'
296
- import tableSetSize from '../TableSetSize/index.vue'
316
+ import tableOperate from '../TableOperate/index.vue'
317
+ import tableShowColumn from '../ShowColumn/index.vue'
318
+
297
319
  import { $lc } from '../../utils/i18n/index.js'
298
320
 
299
321
  const renderer = {
@@ -313,7 +335,8 @@ const renderer = {
313
335
  export default {
314
336
  name: 'TablePro',
315
337
  components: {
316
- tableSetSize,
338
+ tableOperate,
339
+ tableShowColumn,
317
340
  empty,
318
341
  renderer
319
342
  },
@@ -359,9 +382,10 @@ export default {
359
382
  return forbidSelect
360
383
  }
361
384
  },
385
+ // 是否显示显示列
362
386
  showColumn: {
363
387
  type: Boolean,
364
- default: false
388
+ default: true
365
389
  },
366
390
  // 数据更新时是否自动清空已选
367
391
  clearSelect: {
@@ -426,13 +450,43 @@ export default {
426
450
  },
427
451
  // 悬浮按钮组隐藏延迟(毫秒)
428
452
  hoverBtnsHideDelay: {
429
- type: Number,
430
- default: 150
453
+ type: Number
431
454
  },
432
455
  // 悬浮按钮组最大显示数量,超过则收起到"更多"下拉菜单
433
456
  hoverBtnsMaxShow: {
434
457
  type: Number,
435
458
  default: 4
459
+ },
460
+ // 列头标签键
461
+ labelKey: {
462
+ type: String,
463
+ default: 'label'
464
+ },
465
+ // 是否自动保存列设置
466
+ autoSave: {
467
+ type: Boolean,
468
+ default: true
469
+ },
470
+ pageId: {
471
+ type: String,
472
+ default: undefined
473
+ },
474
+ isFilter: {
475
+ type: Boolean,
476
+ default: false
477
+ },
478
+ width: {
479
+ type: String,
480
+ default: '1000px'
481
+ },
482
+ hasPX: {
483
+ type: Boolean,
484
+ default: false
485
+ },
486
+ // 导出函数
487
+ exportFn: {
488
+ type: Function,
489
+ default: null
436
490
  }
437
491
  },
438
492
  data() {
@@ -454,16 +508,19 @@ export default {
454
508
  isDropdownVisible: false, // "更多"下拉菜单是否展开
455
509
  hoverHeaderProp: null, // 当前悬停表头列的 prop
456
510
  hoverIconKey: null, // 当前悬停的静态列头图标标识
457
- isExpand: false
511
+ isExpand: false,
512
+ isExport: false, // 是否导出
513
+ dialogVisible: false, // 显示列设置对话框
514
+ checkColumns: this.columns.slice() // 显示列设置对话框中已选择的列(默认使用 columns prop)
458
515
  }
459
516
  },
460
517
  computed: {
461
518
  _columns: {
462
519
  get() {
463
520
  if (this.isAutoWidth) {
464
- return this.calcColumnWidth(this.columns)
521
+ return this.calcColumnWidth(this.checkColumns)
465
522
  } else {
466
- return this.columns
523
+ return this.checkColumns
467
524
  }
468
525
  },
469
526
  set(val) {
@@ -502,14 +559,18 @@ export default {
502
559
  },
503
560
  // 计算列宽
504
561
  clacStaticColumnWidth() {
505
- const hasExpand = this.$attrs.expandConfig || this.$attrs['expand-config']
562
+ const hasExpand = this.$attrs.treeConfig || this.$attrs['tree-config']
506
563
  const activeCount = [this.showColumn, this.showSetsize, hasExpand].filter(Boolean).length
507
- return activeCount === 3 ? 100 : activeCount === 2 ? 80 : 50
564
+ return activeCount === 3 ? 112 : 76
508
565
  }
509
566
  },
510
567
  watch: {
511
568
  columns() {
512
569
  this.colsKey = this.colsKey + 1
570
+ // 没有 pageId 时,columns 变更同步更新 checkColumns
571
+ if (!this.pageId) {
572
+ this.checkColumns = this.columns.slice()
573
+ }
513
574
  },
514
575
  size(val) {
515
576
  this.sizeC = val
@@ -524,12 +585,44 @@ export default {
524
585
  },
525
586
  activated() {
526
587
  this.$refs.vxeTable.loadData(this.data)
588
+ if (this.showColumn && this.pageId) {
589
+ this.getColumns()
590
+ }
527
591
  },
528
592
  beforeDestroy() {
529
593
  // 清理定时器
530
594
  this.clearHoverTimers()
531
595
  },
596
+ mounted() {
597
+ if (this.showColumn && this.pageId) {
598
+ this.getColumns()
599
+ }
600
+ },
532
601
  methods: {
602
+ openExportColumn() {
603
+ this.dialogVisible = true
604
+ this.isExport = true
605
+ },
606
+ resizableChange({ resizeWidth, columnIndex }) {
607
+ this.checkColumns[columnIndex].width = resizeWidth
608
+ this.$refs.showColumn.saveColumns(this.checkColumns)
609
+ },
610
+ setColumns(list) {
611
+ if (this.isExport) {
612
+ this.exportFn(list)
613
+ } else {
614
+ this.checkColumns = list
615
+ }
616
+ },
617
+ async getColumns() {
618
+ try {
619
+ const columns = await this.$refs.showColumn.getColumns(this.pageId)
620
+ this.checkColumns = columns?.length ? columns : this.columns
621
+ } catch (err) {
622
+ // API 请求失败时回退到 columns prop
623
+ this.checkColumns = this.columns
624
+ }
625
+ },
533
626
  /**
534
627
  * 一键展开/折叠表格树形行(仅处理第一层级数据行)
535
628
  * 通过 vxe-table 的 setTreeExpand API 批量设置顶层行的展开状态,
@@ -722,7 +815,7 @@ export default {
722
815
  // 输出全部条件
723
816
  const obj = {}
724
817
  // 复制默认筛选条件为空
725
- this.columns.forEach((item) => {
818
+ this.checkColumns.forEach((item) => {
726
819
  if (item.filters) {
727
820
  this.$set(obj, item.prop, undefined)
728
821
  }
@@ -1000,69 +1093,64 @@ export default {
1000
1093
  }
1001
1094
  },
1002
1095
  // ========== 列宽计算相关方法 ==========
1096
+ getRowClassName({ row }) {
1097
+ const checkedRows = this.$refs.vxeTable?.getCheckboxRecords(false) || []
1098
+ const checkedSet = new Set(checkedRows)
1099
+ return checkedSet.has(row) ? 'n20-table-pro__row-checked' : ''
1100
+ },
1003
1101
  calcColumnWidth(columns) {
1004
- columns = columns.map((item) => {
1005
- return {
1006
- ...item,
1007
- _width_: 0
1008
- }
1009
- })
1102
+ // 常量配置
1103
+ const CHAR_WIDTH = 20 // 每个字符的平均宽度(像素)
1104
+ const PADDING = 20 // 左右padding
1105
+ const CHECKBOX_WIDTH = 50 // 复选框列宽度
1106
+ const OPERATE_WIDTH = 180 // 操作列宽度
1107
+ const HOVER_BTNS_WIDTH = 356 // 悬浮按钮组宽度
1108
+ const MIN_LABEL_LENGTH = 10 // 最小标签长度
1010
1109
 
1011
- // 优先使用表格容器的宽度,如果没有则使用app容器宽度
1110
+ // 获取容器宽度
1012
1111
  let wrapperEl = this.$refs.vxeTable?.$el
1013
- if (!wrapperEl) {
1014
- wrapperEl = document.querySelector('div#app')
1015
- }
1016
- if (!wrapperEl) {
1017
- return columns
1018
- }
1019
- const { width: windowWidth } = wrapperEl.getBoundingClientRect()
1020
- // 定义每个字符的平均宽度(像素)
1021
- const CHAR_WIDTH = 20 // 根据实际字体大小调整
1022
- const PADDING = 20 // 左右padding
1112
+ if (!wrapperEl) wrapperEl = document.querySelector('div#app')
1113
+ if (!wrapperEl) return columns
1023
1114
 
1024
- function calc(columns) {
1025
- // 计算所有列的基础宽度总和
1026
- let totalBaseWidth = 0
1027
- columns.forEach((column) => {
1028
- if (column.static && column.label === $lc('操作') && !column.width && !column.minWidth) {
1029
- column.width = 180
1030
- }
1031
- if (column.type === 'checkbox') {
1032
- column.width = 50
1033
- }
1115
+ const { width: containerWidth } = wrapperEl.getBoundingClientRect()
1034
1116
 
1035
- // 如果没有设置宽度,根据字符数计算最小宽度
1036
- if (!column.width && !column.minWidth && !column['min-width']) {
1037
- const textLength = (column.label && column.label.length) || 10
1038
- column.minWidth = Math.ceil(textLength * CHAR_WIDTH + PADDING)
1039
- }
1117
+ // 解析宽度值(支持数字、"100"、"100px"格式)
1118
+ const parseWidth = (value) => (typeof value === 'number' ? value : parseInt(value, 10) || 0)
1040
1119
 
1041
- // 计算基础宽度:有width的用width,没有的用minWidth
1042
- const widthValue = column.width || column.minWidth || column['min-width'] || 0
1043
- // 处理不同格式的宽度:数字、"100"、"100px"
1044
- let baseWidth = 0
1045
- if (typeof widthValue === 'number') {
1046
- baseWidth = widthValue
1047
- } else if (typeof widthValue === 'string') {
1048
- // 提取字符串中的数字部分
1049
- baseWidth = parseInt(widthValue) || 0
1050
- }
1051
- column['_baseWidth_'] = baseWidth
1052
- totalBaseWidth += baseWidth
1053
- })
1054
- // 如果所有列的基础宽度总和 >= 容器宽度,不做处理
1055
- if (totalBaseWidth >= windowWidth) {
1056
- return columns
1057
- } else {
1058
- const seqColumns = columns.filter((item) => item.type !== 'seq' && item.type !== 'checkbox')
1059
- if (seqColumns.length > 0) {
1060
- seqColumns[0].width = ''
1061
- }
1062
- return columns
1120
+ // 计算列宽并统计总宽度
1121
+ let totalWidth = 0
1122
+ const calcColumns = columns.map((column) => {
1123
+ // 操作列固定宽度
1124
+ if (column.static && column.label === $lc('操作') && !column.width && !column.minWidth) {
1125
+ column.width = OPERATE_WIDTH
1126
+ }
1127
+ // 复选框列固定宽度
1128
+ if (column.type === 'checkbox') {
1129
+ column.width = CHECKBOX_WIDTH
1130
+ }
1131
+ // 未设置宽度时,根据标签字符数计算最小宽度
1132
+ if (!column.width && !column.minWidth && !column['min-width']) {
1133
+ const textLength = column.label?.length || MIN_LABEL_LENGTH
1134
+ column.minWidth = Math.ceil(textLength * CHAR_WIDTH + PADDING)
1135
+ }
1136
+ // 计算基础宽度
1137
+ const widthValue = column.width || column.minWidth || column['min-width'] || 0
1138
+ const baseWidth = parseWidth(widthValue)
1139
+ column._baseWidth_ = baseWidth
1140
+ totalWidth += baseWidth
1141
+ return column
1142
+ })
1143
+
1144
+ // 悬浮按钮:给最后一列预留按钮组空间
1145
+ if (this.btnList?.length && calcColumns.length > 0) {
1146
+ const lastColumn = calcColumns[calcColumns.length - 1]
1147
+ const baseWidth = lastColumn._baseWidth_ || 0
1148
+ if (baseWidth <= HOVER_BTNS_WIDTH) {
1149
+ lastColumn.width = HOVER_BTNS_WIDTH + baseWidth
1063
1150
  }
1151
+ lastColumn.align = 'left'
1064
1152
  }
1065
- return calc(columns)
1153
+ return calcColumns
1066
1154
  }
1067
1155
  }
1068
1156
  }
@@ -2,8 +2,8 @@
2
2
  <el-dropdown @command="setSize">
3
3
  <i
4
4
  v-title="$lc('行高')"
5
- class="v3-icon-line-height pointer"
6
- :class="hoverIconKey === 'height' ? 'color-primary' : ''"
5
+ class="v3-icon-line-height pointer color-white"
6
+ :class="hoverIconKey === 'height' ? 'color-white' : ''"
7
7
  @mouseenter="hoverIconKey = 'height'"
8
8
  @mouseleave="hoverIconKey = null"
9
9
  ></i>
@@ -26,7 +26,7 @@ export default {
26
26
  type: Object,
27
27
  default: () => ({
28
28
  border: 'inner',
29
- size: 'mini',
29
+ size: 'small',
30
30
  stripe: false
31
31
  })
32
32
  },
@@ -0,0 +1,82 @@
1
+ <template>
2
+ <div class="el-table-set-size flex-box">
3
+ <div class="el-table-set-size-item m-r-0">
4
+ <i
5
+ v-title="$lc('设置显示列')"
6
+ class="v3-icon-system-solution pointer color-white"
7
+ :class="hoverIconKey === 'showColumn' ? 'color-white' : ''"
8
+ @mouseenter="hoverIconKey = 'showColumn'"
9
+ @mouseleave="hoverIconKey = null"
10
+ @click="$emit('visible-column')"
11
+ ></i>
12
+ </div>
13
+ <div class="el-table-set-size-item m-r-0">
14
+ <tableSetSize
15
+ :size="sizeC"
16
+ v-bind="$attrs"
17
+ @update:size="(row) => $emit('update:size', row)"
18
+ @resize="(row) => $emit('resize', row)"
19
+ />
20
+ </div>
21
+ <div class="el-table-set-size-item m-r-0">
22
+ <i
23
+ v-title="!isExpand ? $lc('展开分组') : $lc('折叠分组')"
24
+ class="pointer"
25
+ :class="[
26
+ isExpand ? 'v3-icon-group-collapse' : 'v3-icon-group-expand',
27
+ hoverIconKey === 'toggleExpand' ? 'color-white' : ''
28
+ ]"
29
+ @mouseenter="hoverIconKey = 'toggleExpand'"
30
+ @mouseleave="hoverIconKey = null"
31
+ @click="$emit('toggle-expand')"
32
+ ></i>
33
+ </div>
34
+ <!-- v-if="$attrs.treeConfig || $attrs['tree-config']"
35
+ <div class="el-table-set-size-item m-r-0" :class="sizeC === 'mini' && 'active'" @click="setSize('mini')">
36
+ <img class="icon-mini" src="./mini.png" />
37
+ <div class="text-mini">{{ _lang === 'zh' ? '小行距' : 'mini' }}</div>
38
+ </div>
39
+ <div class="el-table-set-size-item" :class="sizeC === 'small' && 'active'" @click="setSize('small')">
40
+ <img class="icon-small" src="./small.png" />
41
+ <div class="text-small">{{ _lang === 'zh' ? '中行距' : 'small' }}</div>
42
+ </div> -->
43
+ </div>
44
+ </template>
45
+
46
+ <script>
47
+ import tableSetSize from './index.vue'
48
+ export default {
49
+ name: 'TableSetSize',
50
+ components: { tableSetSize },
51
+ props: {
52
+ size: {
53
+ type: String,
54
+ default: 'small'
55
+ },
56
+ mini: {
57
+ type: Object,
58
+ default: () => ({
59
+ border: true,
60
+ size: 'mini',
61
+ stripe: true
62
+ })
63
+ },
64
+ small: {
65
+ type: Object,
66
+ default: () => ({
67
+ border: true,
68
+ size: 'small',
69
+ stripe: false
70
+ })
71
+ }
72
+ },
73
+ data() {
74
+ let _this = this
75
+ return {
76
+ isExpand: false,
77
+ hoverIconKey: null, // 当前悬停的静态列头图标标识
78
+ sizeC: localStorage.getItem('table-size') || _this.size
79
+ }
80
+ }
81
+ }
82
+ </script>
@@ -0,0 +1,64 @@
1
+ <template>
2
+ <div class="n20-tabs__wrapper">
3
+ <el-tabs :value="init" class="n20-tabs__tab" type="card" :before-leave="beforeFn" @tab-click="clickFn">
4
+ <el-tab-pane
5
+ v-for="item of data"
6
+ :key="item.name"
7
+ :tab-info="item"
8
+ :name="item.name"
9
+ :icon="item.icon"
10
+ :disabled="item.disabled"
11
+ >
12
+ <template slot="label">
13
+ <span v-if="item.icon" :class="item.icon"></span>
14
+ <sup v-if="item.badge" class="el-tabs__item-badge"></sup>
15
+ <span v-if="item.content" v-title="`${item.content}`"> {{ item.name }}</span>
16
+ <span v-else>{{ item.name }}</span>
17
+ </template>
18
+ </el-tab-pane>
19
+ </el-tabs>
20
+ <div class="n20-tabs__right">
21
+ <slot></slot>
22
+ </div>
23
+ </div>
24
+ </template>
25
+
26
+ <script>
27
+ import { $lc } from '../../utils/i18n/index'
28
+ export default {
29
+ name: 'Tabs',
30
+ props: {
31
+ data: {
32
+ type: Array,
33
+ default: () => []
34
+ },
35
+ init: {
36
+ type: String,
37
+ default: ''
38
+ },
39
+ size: {
40
+ type: String,
41
+ default: 'mini'
42
+ }
43
+ },
44
+ computed: {
45
+ stop() {
46
+ return !this.$listeners['update:init']
47
+ }
48
+ },
49
+ methods: {
50
+ clickFn(C) {
51
+ let item = C.$attrs['tab-info']
52
+ if (this.$listeners['update:init']) {
53
+ !item.disabled && this.$emit('update:init', item.name)
54
+ }
55
+ if (this.$listeners['click']) {
56
+ this.$emit('click', item)
57
+ }
58
+ },
59
+ beforeFn(name) {
60
+ return name === this.init ? true : !this.stop
61
+ }
62
+ }
63
+ }
64
+ </script>
package/src/index.js CHANGED
@@ -42,7 +42,7 @@ import InputSearch from './components/InputSearch/index.vue'
42
42
  import NavMenu from './components/NavMenu/index.vue'
43
43
  import PageHeader from './components/PageHeader/index.vue'
44
44
  import Page from './components/PageLayout/page.vue'
45
- import Pagination from './components/Pagination/index.vue'
45
+ import Pagination from './components/Pagination/main.vue'
46
46
  import SecondaryTab from './components/SecondaryTab/index.vue'
47
47
  import SelectLazy from './components/SelectLazy/index.vue'
48
48
  import SelectTreeLazy from './components/SelectTree/SelectTreeLazy.vue'
@@ -75,6 +75,7 @@ import HandlingAdvice from './components/HandlingAdvice/index.vue'
75
75
  import Preview from './components/Preview/index.vue'
76
76
  import SelectTreePro from './components/SelectTree/pro.vue'
77
77
  import Tree from './components/Tree/index.vue'
78
+ import Tabs from './components/Tabs/index.vue'
78
79
 
79
80
  // 新版日期选择框
80
81
  import BusiDatePicker from './components/DateSelect/busiDate.vue'
@@ -207,6 +208,7 @@ const components = [
207
208
  ShowColumn,
208
209
  Page,
209
210
  Task,
211
+ Tabs,
210
212
  IconGroupButton,
211
213
  Anchor,
212
214
  AnchorItem,
@@ -383,6 +385,7 @@ export {
383
385
  TertiaryTab,
384
386
  TimePicker,
385
387
  Tree,
388
+ Tabs,
386
389
  Upload,
387
390
  UploadMsg,
388
391
  WorkCard,
@@ -98,7 +98,7 @@ const ASCII_W = {
98
98
  }
99
99
 
100
100
  export default function getWidth(label) {
101
- label = label || ''
101
+ label = String(label || '')
102
102
  let labels = label.match(/./gu) || []
103
103
  let labelW = 0
104
104
  labels.forEach((s) => (labelW += ASCII_W[s] || 14))
@@ -233,7 +233,7 @@ function request(opt) {
233
233
  delete debounceObj[opt.method + opt.url]
234
234
 
235
235
  closeLoading({ loading })
236
- })
236
+ }).catch(() => {}) // 防止 finally 返回的丢弃 Promise 产生未处理的 rejection
237
237
  debounceObj[opt.method + opt.url] = resPro
238
238
  return resPro
239
239
  }