backend-management-ui 1.7.10 → 1.7.12

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 (3) hide show
  1. package/README.md +247 -236
  2. package/index.common.js +68 -41
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -5,6 +5,7 @@
5
5
  现有组件:ui-form、ui-table、ui-btns、ui-dialog、ui-virtual-select、status
6
6
 
7
7
  ## 特性
8
+
8
9
  - 基于ElementUI的二次封装,完全兼容ElementUI原有API与功能,无需额外适配
9
10
  - 极简配置化开发:表格 / 表单 / 按钮组等组件通过 JSON 配置快速生成,无需重复写模板
10
11
  - 高频业务场景全覆盖:内置配置化表格、表单、按钮组、虚拟滚动下拉框等核心组件
@@ -12,6 +13,7 @@
12
13
  - 基于 ElSelect + vue-virtual-scroll-list 实现海量数据下拉选择,解决大数据渲染卡顿问题
13
14
 
14
15
  ## 安装
16
+
15
17
  npm 安装
16
18
 
17
19
  `npm install backend-management-ui --save`
@@ -29,6 +31,7 @@ yarn 安装
29
31
  `npm install vue-virtual-scroll-list --save`
30
32
 
31
33
  ## 快速上手
34
+
32
35
  全局引入
33
36
 
34
37
  ``` js
@@ -71,69 +74,75 @@ export default {
71
74
  #### 典型编辑型表单
72
75
 
73
76
  ``` js
74
- <ui-form :model="searchForm" :formConfig="formConfig" label-width="100px" ></ui-form>
77
+ <template>
78
+ <ui-form :model="searchForm" :formConfig="formConfig" label-width="100px"></ui-form>
79
+ </template>
80
+
75
81
  <script>
76
- export default {
77
- data() {
78
- return {
79
- searchForm: {
80
- orderNo: null,
81
- status: null
82
+ export default {
83
+ data() {
84
+ return {
85
+ searchForm: {
86
+ orderNo: null,
87
+ status: null
88
+ },
89
+ formConfig: [
90
+ {
91
+ label: '订单号',
92
+ prop: 'orderNo',
93
+ component: 'el-input'
82
94
  },
83
- formConfig: [
84
- {
85
- label: '订单号',
86
- prop: 'orderNo',
87
- component: 'el-input'
88
- },
89
- {
90
- label: '状态',
91
- prop: 'status',
92
- component: 'el-select',
93
- options: [
94
- {label: '成功', value: 0},
95
- {label: '失败', value: 1}
96
- ]
97
- }
98
- ]
99
- }
95
+ {
96
+ label: '状态',
97
+ prop: 'status',
98
+ component: 'el-select',
99
+ options: [
100
+ {label: '成功', value: 0},
101
+ {label: '失败', value: 1}
102
+ ]
103
+ }
104
+ ]
100
105
  }
101
106
  }
107
+ }
102
108
  </script>
103
109
  ```
104
110
 
105
111
  #### 典型展示表单
106
112
 
107
113
  ``` js
108
- <ui-form :model="searchForm" :formConfig="formConfig" label-width="100px" :showOperateBtn="false">
109
- <template #item-orderNo="{ item, model, index }">
110
- <span>{{ model.orderNo }}</span>
114
+ <template>
115
+ <ui-form :model="searchForm" :formConfig="formConfig" label-width="100px" :showOperateBtn="false">
116
+ <template #item-orderNo="{ item, model, index }">
117
+ <span>{{ model.orderNo }}</span>
118
+ </template>
119
+ <template #item-status="{ model }">
120
+ <span>{{ model.status }}</span>
121
+ </template>
122
+ </ui-form>
111
123
  </template>
112
- <template #item-status="{ model }">
113
- <span>{{ model.status }}</span>
114
- </template>
115
- </ui-form>
124
+
116
125
  <script>
117
- export default {
118
- data() {
119
- return {
120
- searchForm: {
121
- orderNo: "订单好xx",
122
- status: "成功"
126
+ export default {
127
+ data() {
128
+ return {
129
+ searchForm: {
130
+ orderNo: "订单好xx",
131
+ status: "成功"
132
+ },
133
+ formConfig: [
134
+ {
135
+ label: '订单号',
136
+ prop: 'orderNo',
123
137
  },
124
- formConfig: [
125
- {
126
- label: '订单号',
127
- prop: 'orderNo',
128
- },
129
- {
130
- label: '状态',
131
- prop: 'status',
132
- }
133
- ]
134
- }
138
+ {
139
+ label: '状态',
140
+ prop: 'status',
141
+ }
142
+ ]
135
143
  }
136
144
  }
145
+ }
137
146
  </script>
138
147
  ```
139
148
 
@@ -146,39 +155,40 @@ export default {
146
155
  <el-button type="primary">导出</el-button>
147
156
  </template>
148
157
  </ui-form>
149
- import { statusApi } from "@/api/status"
158
+
150
159
  <script>
151
- export default {
152
- data() {
153
- return {
154
- searchForm: {
155
- orderNo: null,
156
- status: null
160
+ import { statusApi } from "@/api/status"
161
+ export default {
162
+ data() {
163
+ return {
164
+ searchForm: {
165
+ orderNo: null,
166
+ status: null
167
+ },
168
+ formConfig: [
169
+ {
170
+ label: '订单号',
171
+ prop: 'orderNo',
172
+ component: 'el-input'
157
173
  },
158
- formConfig: [
159
- {
160
- label: '订单号',
161
- prop: 'orderNo',
162
- component: 'el-input'
163
- },
164
- {
165
- label: '状态',
166
- prop: 'status',
167
- component: 'el-select',
168
- api: statusApi,
169
- {/* 或者 */}
170
- {/* api: {
171
- url: statusApi,
172
- params: {
173
- page: 1,
174
- pageSize: 10,
175
- }
176
- } */}
177
- }
178
- ]
179
- }
174
+ {
175
+ label: '状态',
176
+ prop: 'status',
177
+ component: 'el-select',
178
+ api: statusApi,
179
+ {/* 或者 */}
180
+ {/* api: {
181
+ url: statusApi,
182
+ params: {
183
+ page: 1,
184
+ pageSize: 10,
185
+ }
186
+ } */}
187
+ }
188
+ ]
180
189
  }
181
190
  }
191
+ }
182
192
  </script>
183
193
  ```
184
194
 
@@ -189,66 +199,66 @@ import { statusApi } from "@/api/status"
189
199
  <ui-form :model="searchForm" :formConfig="formConfig" inline label-width="100px">
190
200
  </ui-form>
191
201
  <script>
192
- export default {
193
- data() {
194
- return {
195
- searchForm: {
196
- orderNo: "订单好xx",
197
- status: "成功"
202
+ export default {
203
+ data() {
204
+ return {
205
+ searchForm: {
206
+ orderNo: "订单好xx",
207
+ status: "成功"
208
+ },
209
+ formConfig: [
210
+ {
211
+ label: "月份区间",
212
+ prop: "dates",
213
+ component: "el-date-picker",
214
+ attrs: {
215
+ type: "month",
216
+ "value-format": "yyyy-MM",
217
+ format: "yyyy年MM月",
218
+ clearable: false, // 所有的表单组件如果有clearable,默认是true
219
+ },
220
+ events: {
221
+ {/* el-date-picker的原生组件事件 */}
222
+ change: (val) => {
223
+ console.log(val)
224
+ },
225
+ },
226
+ }
227
+ {
228
+ label: '订单号',
229
+ prop: 'orderNo',
230
+ component: 'el-input',
231
+ {/* Form-Item Attributes */}
232
+ formItemAttrs: {
233
+ "label-width": "120px",
234
+ size: "small"
235
+ },
198
236
  },
199
- formConfig: [
200
- {
201
- label: "月份区间",
202
- prop: "dates",
203
- component: "el-date-picker",
204
- attrs: {
205
- type: "month",
206
- "value-format": "yyyy-MM",
207
- format: "yyyy年MM月",
208
- clearable: false, // 所有的表单组件如果有clearable,默认是true
237
+ {
238
+ label: '状态',
239
+ prop: 'status',
240
+ component: 'el-select',
241
+ {/* 表单组件属性 */}
242
+ attrs: {
243
+ style: {
244
+ width: "200px", // 默认220px
209
245
  },
246
+ filterable: true,
210
247
  events: {
211
- {/* el-date-picker的原生组件事件 */}
212
248
  change: (val) => {
213
249
  console.log(val)
214
- },
215
- },
216
- }
217
- {
218
- label: '订单号',
219
- prop: 'orderNo',
220
- component: 'el-input',
221
- {/* Form-Item Attributes */}
222
- formItemAttrs: {
223
- "label-width": "120px",
224
- size: "small"
225
- },
226
- },
227
- {
228
- label: '状态',
229
- prop: 'status',
230
- component: 'el-select',
231
- {/* 表单组件属性 */}
232
- attrs: {
233
- style: {
234
- width: "200px", // 默认220px
235
- },
236
- filterable: true,
237
- events: {
238
- change: (val) => {
239
- console.log(val)
240
- }
241
250
  }
242
- },
243
- {/* options有长度时不会触发api */}
244
- options: [
245
- { label: "成功", value: 0 }
246
- ]
247
- }
248
- ]
249
- }
251
+ }
252
+ },
253
+ {/* options有长度时不会触发api */}
254
+ options: [
255
+ { label: "成功", value: 0 }
256
+ ]
257
+ }
258
+ ]
250
259
  }
251
260
  }
261
+ }
252
262
  </script>
253
263
  ```
254
264
 
@@ -317,104 +327,103 @@ import { statusApi } from "@/api/status"
317
327
  </template>
318
328
  </ui-table>
319
329
  <script>
320
- export default {
321
- data() {
322
- return {
323
- loading: false,
324
- tableColumns: [
325
- {
326
- label: "测试1",
327
- prop: "test1",
328
- "min-width": 150,
329
- "show-overflow-tooltip": true,
330
- fixed: "left",
331
- },
332
- {
333
- label: "测试render一大一小的两行数据",
334
- prop: "test2",
335
- "min-width": 150,
336
- "show-overflow-tooltip": true,
337
- render: ({ row, column, $h, index }) => {
338
- const { test2, test2Code } = row;
339
- return $h("div", { style: { width: "100%" } }, [
340
- $h("div", { class: "bm-table-cell" }, test2),
341
- $h("div", { style: { color: "#AAAAAA", fontSize: "12px" } }, test2Code),
342
- ]);
343
- }, // 单元格render形式
344
- },
345
- {
346
- label: "测试组件",
347
- prop: "test3",
348
- width: 200,
349
- component: 'Status', // 单元格使用component组件形式时,默认会把row,column,index 传入组件
350
- componentProps: { statusName: "test3" }, // componentProps组件需要的参数
351
- {/* componentEvents: {
352
- change: (val) => {},
353
- ...
354
- } // 组件的事件,如果有的话 */}
355
- },
356
- {
357
- label: "测试4",
358
- prop: "test4",
359
- width: 100,
360
- formatter: (val, row, index) => val || "-", // 单元格内容格式化
361
- },
362
- {
363
- headerSlot: true, // 表头使用插槽
364
- prop: "test5",
365
- slot: true // 单元格插槽形式
366
- },
367
- {
368
- label: "测试5-可点击的单元格", // 默认active样式
369
- prop: "test5",
370
- width: 100,
371
- clickable: true, // 一直可点击
372
-
373
- {/* 或者使用条件判断
374
- clickableClass: ({row}, col) => row[col.prop] > 0 */}
375
- onCellClick: ({row, col, index}) => {} // 单元格可点击时触发的方法
376
- }
377
- ],
378
- tableData: [],
379
- pagination: {
380
- pageNum: 1,
381
- pageSize: 10
330
+ export default {
331
+ data() {
332
+ return {
333
+ loading: false,
334
+ tableColumns: [
335
+ {
336
+ label: "测试1",
337
+ prop: "test1",
338
+ "min-width": 150,
339
+ "show-overflow-tooltip": true,
340
+ fixed: "left",
382
341
  },
383
- total: 0,
384
- operateBtns: [
385
- {
386
- label: "详情",
387
- type: "text",
388
- action: (params) => {
389
-
390
- },
391
- },
392
- {
393
- label: "操作记录",
394
- type: "text",
395
- action: ({ context }) => {
396
- this.currentRow = context;
397
- this.getOperateLogInfo();
398
- },
399
- },
400
- ],
401
- currentRow: null
402
- }
403
- },
404
- methods: {
405
- init() {},
406
- handleChangePagination(pagination) {
407
- this.pagination = pagination
408
- this.init()
342
+ {
343
+ label: "测试render一大一小的两行数据",
344
+ prop: "test2",
345
+ "min-width": 150,
346
+ "show-overflow-tooltip": true,
347
+ render: ({ row, column, $h, index }) => {
348
+ const { test2, test2Code } = row;
349
+ return $h("div", { style: { width: "100%" } }, [
350
+ $h("div", { class: "bm-table-cell" }, test2),
351
+ $h("div", { style: { color: "#AAAAAA", fontSize: "12px" } }, test2Code),
352
+ ]);
353
+ }, // 单元格render形式
354
+ },
355
+ {
356
+ label: "测试组件",
357
+ prop: "test3",
358
+ width: 200,
359
+ component: 'Status', // 单元格使用component组件形式时,默认会把row,column,index 传入组件
360
+ componentProps: { statusName: "test3" }, // componentProps组件需要的参数
361
+ {/* componentEvents: {
362
+ change: (val) => {},
363
+ ...
364
+ } // 组件的事件,如果有的话 */}
365
+ },
366
+ {
367
+ label: "测试4",
368
+ prop: "test4",
369
+ width: 100,
370
+ formatter: (val, row, index) => val || "-", // 单元格内容格式化
371
+ },
372
+ {
373
+ headerSlot: true, // 表头使用插槽
374
+ prop: "test5",
375
+ slot: true // 单元格插槽形式
376
+ },
377
+ {
378
+ label: "测试5-可点击的单元格", // 默认active样式
379
+ prop: "test5",
380
+ width: 100,
381
+ clickable: true, // 一直可点击 render形式、组件形式和插槽形式时不生效
382
+
383
+ {/* 或者使用条件判断
384
+ clickableClass: ({row}, col) => row[col.prop] > 0 */}
385
+ onCellClick: ({row, col, index}) => {} // 单元格可点击时触发的方法
386
+ }
387
+ ],
388
+ tableData: [],
389
+ pagination: {
390
+ pageNum: 1,
391
+ pageSize: 10
409
392
  },
410
- handleSelectionChange(selection) {},
411
- getOperateLogInfo() {}
393
+ total: 0,
394
+ operateBtns: [
395
+ {
396
+ label: "详情",
397
+ type: "text",
398
+ action: (params) => {
399
+
400
+ },
401
+ },
402
+ {
403
+ label: "操作记录",
404
+ type: "text",
405
+ action: ({ context }) => {
406
+ this.currentRow = context;
407
+ this.getOperateLogInfo();
408
+ },
409
+ },
410
+ ],
411
+ currentRow: null
412
412
  }
413
+ },
414
+ methods: {
415
+ init() {},
416
+ handleChangePagination(pagination) {
417
+ this.pagination = pagination
418
+ this.init()
419
+ },
420
+ handleSelectionChange(selection) {},
421
+ getOperateLogInfo() {}
413
422
  }
423
+ }
414
424
  </script>
415
425
  ```
416
426
 
417
-
418
427
  #### props & slots & methods
419
428
 
420
429
  ##### props
@@ -486,18 +495,18 @@ import { statusApi } from "@/api/status"
486
495
  </ui-dialog>
487
496
 
488
497
  <script>
489
- export default {
490
- data() {
491
- return {
492
- show: false,
493
- }
494
- },
495
- methods: {
496
- handleClose() {},
497
- handleCancel() {},
498
- handleCancel() {},
498
+ export default {
499
+ data() {
500
+ return {
501
+ show: false,
499
502
  }
503
+ },
504
+ methods: {
505
+ handleClose() {},
506
+ handleCancel() {},
507
+ handleCancel() {},
500
508
  }
509
+ }
501
510
  </script>
502
511
  ```
503
512
 
@@ -538,17 +547,19 @@ import { statusApi } from "@/api/status"
538
547
  <ui-virtual-select v-model="select" multiple filterable :options="options"/>
539
548
 
540
549
  <script>
541
- export default {
542
- data() {
543
- return {
544
- select: []
545
- options: Array.from({ length: 1000 }, (_, index) => ({ label: `${index + 1}虚拟滚动数据`, value: index + 1 }))
546
- }
550
+ export default {
551
+ data() {
552
+ return {
553
+ select: []
554
+ options: Array.from({ length: 1000 }, (_, index) => ({ label: `${index + 1}虚拟滚动数据`, value: index + 1 }))
547
555
  }
548
556
  }
557
+ }
549
558
  </script>
550
559
  ```
551
560
 
561
+ -------------------
562
+
552
563
  #### props
553
564
 
554
565
  | 参数 | 说明 | 类型 | 可选值 | 默认值 |
package/index.common.js CHANGED
@@ -28,7 +28,6 @@ var _startsWithInstanceProperty = require('@babel/runtime-corejs3/core-js-stable
28
28
  var _endsWithInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/ends-with');
29
29
  var _toConsumableArray = require('@babel/runtime-corejs3/helpers/esm/toConsumableArray');
30
30
  var _concatInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/concat');
31
- var _JSON$stringify = require('@babel/runtime-corejs3/core-js-stable/json/stringify');
32
31
  var _findIndexInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/find-index');
33
32
  var _spliceInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/splice');
34
33
  var VueVirtualScrollList = require('vue-virtual-scroll-list');
@@ -61,7 +60,6 @@ var _startsWithInstanceProperty__default = /*#__PURE__*/_interopDefaultLegacy(_s
61
60
  var _endsWithInstanceProperty__default = /*#__PURE__*/_interopDefaultLegacy(_endsWithInstanceProperty);
62
61
  var _toConsumableArray__default = /*#__PURE__*/_interopDefaultLegacy(_toConsumableArray);
63
62
  var _concatInstanceProperty__default = /*#__PURE__*/_interopDefaultLegacy(_concatInstanceProperty);
64
- var _JSON$stringify__default = /*#__PURE__*/_interopDefaultLegacy(_JSON$stringify);
65
63
  var _findIndexInstanceProperty__default = /*#__PURE__*/_interopDefaultLegacy(_findIndexInstanceProperty);
66
64
  var _spliceInstanceProperty__default = /*#__PURE__*/_interopDefaultLegacy(_spliceInstanceProperty);
67
65
  var VueVirtualScrollList__default = /*#__PURE__*/_interopDefaultLegacy(VueVirtualScrollList);
@@ -539,8 +537,9 @@ var renderNode = {
539
537
  },
540
538
  render: function render(h, ctx) {
541
539
  try {
542
- var render = ctx.render,
543
- params = ctx.params;
540
+ var _ctx$props = ctx.props,
541
+ render = _ctx$props.render,
542
+ params = _ctx$props.params;
544
543
  var vnode = render(params);
545
544
  return vnode || h('span', '');
546
545
  } catch (error) {
@@ -666,13 +665,14 @@ var script$5 = {
666
665
  },
667
666
  getRenderParams: function getRenderParams(scope) {
668
667
  return {
669
- row: scope.row,
668
+ row: scope.row || {},
670
669
  column: scope.column,
671
670
  $h: this.$createElement,
672
- index: scope.$index
671
+ index: scope.$index || 0
673
672
  };
674
673
  },
675
674
  getCellActiveClass: function getCellActiveClass(scope, col) {
675
+ if (col.clickable) return true;
676
676
  if (typeof col.clickableClass === "function") {
677
677
  return col.clickableClass(scope, col);
678
678
  }
@@ -875,14 +875,14 @@ var __vue_staticRenderFns__$5 = [];
875
875
  /* style */
876
876
  var __vue_inject_styles__$5 = function __vue_inject_styles__(inject) {
877
877
  if (!inject) return;
878
- inject("data-v-071ee91e_0", {
879
- source: ".bm-table-container[data-v-071ee91e]{box-sizing:border-box}.bm-table-container .bm-pagination[data-v-071ee91e]{display:flex;justify-content:flex-end;margin-top:20px}.bm-table-container .bm-table-cell[data-v-071ee91e]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.bm-table-container .bm-cell-active[data-v-071ee91e]{color:#02a7f0;cursor:pointer}.bm-table-container[data-v-071ee91e] :deep(.el-tablethead){color:#606266}",
878
+ inject("data-v-089a18c2_0", {
879
+ source: ".bm-table-container[data-v-089a18c2]{box-sizing:border-box}.bm-table-container .bm-pagination[data-v-089a18c2]{display:flex;justify-content:flex-end;margin-top:20px}.bm-table-container .bm-table-cell[data-v-089a18c2]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.bm-table-container .bm-cell-active[data-v-089a18c2]{color:#02a7f0;cursor:pointer}.bm-table-container[data-v-089a18c2] :deep(.el-tablethead){color:#606266}",
880
880
  map: undefined,
881
881
  media: undefined
882
882
  });
883
883
  };
884
884
  /* scoped */
885
- var __vue_scope_id__$5 = "data-v-071ee91e";
885
+ var __vue_scope_id__$5 = "data-v-089a18c2";
886
886
  /* module identifier */
887
887
  var __vue_module_identifier__$5 = undefined;
888
888
  /* functional template */
@@ -1273,6 +1273,11 @@ var __vue_component__$2 = /*#__PURE__*/normalizeComponent({
1273
1273
  //
1274
1274
  //
1275
1275
  //
1276
+ //
1277
+ //
1278
+ //
1279
+ //
1280
+ //
1276
1281
 
1277
1282
  var script$1 = {
1278
1283
  name: 'UiVirtualSelectItem',
@@ -1281,6 +1286,9 @@ var script$1 = {
1281
1286
  type: Object,
1282
1287
  "default": function _default() {
1283
1288
  return {};
1289
+ },
1290
+ validator: function validator(val) {
1291
+ return _typeof__default["default"](val) === 'object' && val !== null && !_Array$isArray__default["default"](val);
1284
1292
  }
1285
1293
  },
1286
1294
  label: {
@@ -1296,11 +1304,17 @@ var script$1 = {
1296
1304
  "default": ''
1297
1305
  }
1298
1306
  },
1307
+ computed: {
1308
+ // 判断 source 是否有效(非空+包含必要属性)
1309
+ isValidSource: function isValidSource() {
1310
+ if (!this.source) return false;
1311
+ return this.label in this.source && this.value in this.source;
1312
+ }
1313
+ },
1299
1314
  methods: {
1300
- // 核心:点击选项时,向上传递选中值
1301
1315
  handleItemClick: function handleItemClick() {
1302
- var selectedValue = this.source[this.value];
1303
- // 触发自定义事件,将选中值传递给父组件
1316
+ if (!this.isValidSource) return;
1317
+ var selectedValue = this.source[this.value] || '';
1304
1318
  this.$emit('item-click', selectedValue);
1305
1319
  }
1306
1320
  }
@@ -1314,34 +1328,42 @@ var __vue_render__$1 = function __vue_render__() {
1314
1328
  var _vm = this;
1315
1329
  var _h = _vm.$createElement;
1316
1330
  var _c = _vm._self._c || _h;
1317
- return _c('el-option', {
1331
+ return _c('div', {
1332
+ staticClass: "virtual-select-item-wrap"
1333
+ }, [_vm.isValidSource ? _c('el-option', {
1318
1334
  staticClass: "item",
1319
1335
  attrs: {
1320
- "label": _vm.source[_vm.label],
1321
- "value": _vm.source[_vm.value]
1336
+ "label": _vm.source[_vm.label] || '',
1337
+ "value": _vm.source[_vm.value] || ''
1322
1338
  },
1323
1339
  on: {
1324
1340
  "click": _vm.handleItemClick
1325
1341
  }
1326
1342
  }, [_c('span', {
1327
1343
  staticClass: "left-text"
1328
- }, [_vm._v(_vm._s(_vm.source[_vm.label]))]), _vm._v(" "), _vm.rightLabel ? _c('span', {
1344
+ }, [_vm._v(_vm._s(_vm.source[_vm.label] || ''))]), _vm._v(" "), _vm.rightLabel && _vm.source[_vm.rightLabel] ? _c('span', {
1329
1345
  staticClass: "right-text"
1330
- }, [_vm._v(_vm._s(_vm.source[_vm.rightLabel]))]) : _vm._e()]);
1346
+ }, [_vm._v(_vm._s(_vm.source[_vm.rightLabel] || ''))]) : _vm._e()]) : _c('el-option', {
1347
+ staticClass: "item empty-item",
1348
+ attrs: {
1349
+ "label": "",
1350
+ "value": ""
1351
+ }
1352
+ })], 1);
1331
1353
  };
1332
1354
  var __vue_staticRenderFns__$1 = [];
1333
1355
 
1334
1356
  /* style */
1335
1357
  var __vue_inject_styles__$1 = function __vue_inject_styles__(inject) {
1336
1358
  if (!inject) return;
1337
- inject("data-v-d0b52dea_0", {
1338
- source: ".left-text[data-v-d0b52dea]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.right-text[data-v-d0b52dea]{margin-left:10px;color:#939393;white-space:nowrap}",
1359
+ inject("data-v-fa4fd644_0", {
1360
+ source: ".virtual-select-item-wrap[data-v-fa4fd644]{display:inline-block;width:100%;height:100%;box-sizing:border-box}.left-text[data-v-fa4fd644]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.right-text[data-v-fa4fd644]{margin-left:10px;color:#939393;white-space:nowrap}.empty-item[data-v-fa4fd644]{height:34px;line-height:34px}",
1339
1361
  map: undefined,
1340
1362
  media: undefined
1341
1363
  });
1342
1364
  };
1343
1365
  /* scoped */
1344
- var __vue_scope_id__$1 = "data-v-d0b52dea";
1366
+ var __vue_scope_id__$1 = "data-v-fa4fd644";
1345
1367
  /* module identifier */
1346
1368
  var __vue_module_identifier__$1 = undefined;
1347
1369
  /* functional template */
@@ -1356,7 +1378,7 @@ var __vue_component__$1 = /*#__PURE__*/normalizeComponent({
1356
1378
  }, __vue_inject_styles__$1, __vue_script__$1, __vue_scope_id__$1, __vue_is_functional_template__$1, __vue_module_identifier__$1, false, createInjector, undefined, undefined);
1357
1379
 
1358
1380
  function ownKeys(e, r) { var t = _Object$keys__default["default"](e); if (_Object$getOwnPropertySymbols__default["default"]) { var o = _Object$getOwnPropertySymbols__default["default"](e); r && (o = _filterInstanceProperty__default["default"](o).call(o, function (r) { return _Object$getOwnPropertyDescriptor__default["default"](e, r).enumerable; })), t.push.apply(t, o); } return t; }
1359
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context6, _context7; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty__default["default"](_context6 = ownKeys(Object(t), !0)).call(_context6, function (r) { _defineProperty__default["default"](e, r, t[r]); }) : _Object$getOwnPropertyDescriptors__default["default"] ? _Object$defineProperties__default["default"](e, _Object$getOwnPropertyDescriptors__default["default"](t)) : _forEachInstanceProperty__default["default"](_context7 = ownKeys(Object(t))).call(_context7, function (r) { _Object$defineProperty__default["default"](e, r, _Object$getOwnPropertyDescriptor__default["default"](t, r)); }); } return e; }
1381
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context4, _context5; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty__default["default"](_context4 = ownKeys(Object(t), !0)).call(_context4, function (r) { _defineProperty__default["default"](e, r, t[r]); }) : _Object$getOwnPropertyDescriptors__default["default"] ? _Object$defineProperties__default["default"](e, _Object$getOwnPropertyDescriptors__default["default"](t)) : _forEachInstanceProperty__default["default"](_context5 = ownKeys(Object(t))).call(_context5, function (r) { _Object$defineProperty__default["default"](e, r, _Object$getOwnPropertyDescriptor__default["default"](t, r)); }); } return e; }
1360
1382
  var isEmptyObject = function isEmptyObject(obj) {
1361
1383
  if (!obj || _typeof__default["default"](obj) !== 'object' || _Array$isArray__default["default"](obj)) return false;
1362
1384
  return _Object$keys__default["default"](obj).length === 0;
@@ -1381,6 +1403,9 @@ var script = {
1381
1403
  value: 'value',
1382
1404
  rightLabel: ''
1383
1405
  };
1406
+ },
1407
+ validator: function validator(val) {
1408
+ return _typeof__default["default"](val) === 'object' && val !== null && 'label' in val && 'value' in val;
1384
1409
  }
1385
1410
  },
1386
1411
  keeps: {
@@ -1412,7 +1437,7 @@ var script = {
1412
1437
  },
1413
1438
  data: function data() {
1414
1439
  return {
1415
- filteredData: _toConsumableArray__default["default"](this.options),
1440
+ filteredData: [],
1416
1441
  maxItemWidth: 0,
1417
1442
  itemComponent: __vue_component__$1,
1418
1443
  innerValue: this.initInnerValue() // 内部维护选中值,避免直接修改props
@@ -1448,7 +1473,8 @@ var script = {
1448
1473
  deep: true,
1449
1474
  immediate: true,
1450
1475
  handler: function handler(val) {
1451
- this.filteredData = _toConsumableArray__default["default"](val);
1476
+ var validOptions = _Array$isArray__default["default"](val) ? val : [];
1477
+ this.filteredData = _toConsumableArray__default["default"](validOptions);
1452
1478
  this.calcMaxItemWidth();
1453
1479
  }
1454
1480
  }
@@ -1475,18 +1501,18 @@ var script = {
1475
1501
  return val === undefined ? null : val;
1476
1502
  },
1477
1503
  calcMaxItemWidth: function calcMaxItemWidth() {
1478
- var _context,
1479
- _this = this;
1480
- if (!this.options.length) return;
1504
+ var _this = this;
1505
+ var validOptions = _Array$isArray__default["default"](this.options) ? this.options : [];
1506
+ if (!validOptions.length) return;
1481
1507
  var temp = document.createElement('div');
1482
1508
  temp.style.cssText = "\n position: absolute;\n top: -9999px;\n left: -9999px;\n white-space: nowrap;\n padding: 0 20px;\n font-size: 14px;\n box-sizing: border-box;\n ";
1483
1509
  document.body.appendChild(temp);
1484
1510
  var maxWidth = 0;
1485
- _forEachInstanceProperty__default["default"](_context = this.options).call(_context, function (item) {
1486
- var _context2;
1487
- var label = item[_this.fields.label] || '';
1511
+ _forEachInstanceProperty__default["default"](validOptions).call(validOptions, function (item) {
1512
+ var _context;
1513
+ var label = (item === null || item === void 0 ? void 0 : item[_this.fields.label]) || '';
1488
1514
  var rightLabel = item[_this.fields.rightLabel] || '';
1489
- temp.innerHTML = _concatInstanceProperty__default["default"](_context2 = "<span>".concat(label, "</span><span style=\"margin-left:10px;color:#939393\">")).call(_context2, rightLabel, "</span>");
1515
+ temp.innerHTML = _concatInstanceProperty__default["default"](_context = "<span>".concat(label, "</span><span style=\"margin-left:10px;color:#939393\">")).call(_context, rightLabel, "</span>");
1490
1516
  maxWidth = Math.max(maxWidth, temp.offsetWidth);
1491
1517
  });
1492
1518
  this.maxItemWidth = maxWidth + 6;
@@ -1507,14 +1533,15 @@ var script = {
1507
1533
  });
1508
1534
  },
1509
1535
  filterMethod: function filterMethod(query) {
1510
- var _context3,
1511
- _this3 = this;
1536
+ var _this3 = this;
1537
+ var validOptions = _Array$isArray__default["default"](this.options) ? this.options : [];
1512
1538
  var lowerQuery = (query === null || query === void 0 ? void 0 : query.toLowerCase()) || '';
1513
- this.filteredData = lowerQuery ? _filterInstanceProperty__default["default"](_context3 = this.options).call(_context3, function (item) {
1539
+ this.filteredData = lowerQuery ? _filterInstanceProperty__default["default"](validOptions).call(validOptions, function (item) {
1540
+ if (!item) return false;
1514
1541
  var label = (item[_this3.fields.label] || '').toLowerCase();
1515
1542
  var rightLabel = _this3.fields.rightLabel ? (item[_this3.fields.rightLabel] || '').toLowerCase() : '';
1516
1543
  return _includesInstanceProperty__default["default"](label).call(label, lowerQuery) || _includesInstanceProperty__default["default"](rightLabel).call(rightLabel, lowerQuery);
1517
- }) : JSON.parse(_JSON$stringify__default["default"](this.options)); // 深拷贝避免引用污染
1544
+ }) : _toConsumableArray__default["default"](validOptions); // 深拷贝避免引用污染
1518
1545
  this.$nextTick(function () {
1519
1546
  var _this3$$refs$virtualL;
1520
1547
  return (_this3$$refs$virtualL = _this3.$refs.virtualList) === null || _this3$$refs$virtualL === void 0 ? void 0 : _this3$$refs$virtualL.scrollToIndex(0);
@@ -1537,14 +1564,14 @@ var script = {
1537
1564
  var isMultiple = (_this$$attrs2 = this.$attrs) === null || _this$$attrs2 === void 0 ? void 0 : _this$$attrs2.multiple; // 判断是否为多选模式
1538
1565
  var normalizedValue = this.normalizeValue(selectedValue);
1539
1566
  if (isMultiple) {
1540
- var _context4;
1567
+ var _context2;
1541
1568
  // 多选:切换选中状态(存在则移除,不存在则添加)
1542
- var valueIndex = _findIndexInstanceProperty__default["default"](_context4 = this.innerValue).call(_context4, function (val) {
1569
+ var valueIndex = _findIndexInstanceProperty__default["default"](_context2 = this.innerValue).call(_context2, function (val) {
1543
1570
  return val === selectedValue;
1544
1571
  });
1545
1572
  if (valueIndex > -1) {
1546
- var _context5;
1547
- _spliceInstanceProperty__default["default"](_context5 = this.innerValue).call(_context5, valueIndex, 1);
1573
+ var _context3;
1574
+ _spliceInstanceProperty__default["default"](_context3 = this.innerValue).call(_context3, valueIndex, 1);
1548
1575
  } else {
1549
1576
  this.innerValue.push(selectedValue);
1550
1577
  }
@@ -1613,14 +1640,14 @@ var __vue_staticRenderFns__ = [];
1613
1640
  /* style */
1614
1641
  var __vue_inject_styles__ = function __vue_inject_styles__(inject) {
1615
1642
  if (!inject) return;
1616
- inject("data-v-4ce656fa_0", {
1617
- source: ".select-wrap[data-v-4ce656fa]{position:relative}.select-wrap .bm-select[data-v-4ce656fa]{width:100%}.virtual-select-popper[data-v-4ce656fa]{padding:0!important;border:1px solid #e4e7ed!important;border-radius:4px!important}.virtual-list[data-v-4ce656fa]{max-height:245px;overflow-y:auto;overflow-x:hidden!important;scrollbar-width:thin;scrollbar-color:#e4e7ed #f5f7fa}.virtual-list[data-v-4ce656fa]::-webkit-scrollbar{width:6px!important;display:block!important}.virtual-list[data-v-4ce656fa]::-webkit-scrollbar-thumb{background-color:#e4e7ed;border-radius:3px}.virtual-list[data-v-4ce656fa]::-webkit-scrollbar-track{background-color:#f5f7fa}[data-v-4ce656fa]:deep(.el-scrollbar__bar.is-vertical){display:none!important}",
1643
+ inject("data-v-2faf6b1a_0", {
1644
+ source: ".select-wrap[data-v-2faf6b1a]{position:relative}.select-wrap .bm-select[data-v-2faf6b1a]{width:100%}.virtual-select-popper[data-v-2faf6b1a]{padding:0!important;border:1px solid #e4e7ed!important;border-radius:4px!important}.virtual-list[data-v-2faf6b1a]{max-height:245px;overflow-y:auto;overflow-x:hidden!important;scrollbar-width:thin;scrollbar-color:#e4e7ed #f5f7fa}.virtual-list[data-v-2faf6b1a]::-webkit-scrollbar{width:6px!important;display:block!important}.virtual-list[data-v-2faf6b1a]::-webkit-scrollbar-thumb{background-color:#e4e7ed;border-radius:3px}.virtual-list[data-v-2faf6b1a]::-webkit-scrollbar-track{background-color:#f5f7fa}[data-v-2faf6b1a]:deep(.el-scrollbar__bar.is-vertical){display:none!important}",
1618
1645
  map: undefined,
1619
1646
  media: undefined
1620
1647
  });
1621
1648
  };
1622
1649
  /* scoped */
1623
- var __vue_scope_id__ = "data-v-4ce656fa";
1650
+ var __vue_scope_id__ = "data-v-2faf6b1a";
1624
1651
  /* module identifier */
1625
1652
  var __vue_module_identifier__ = undefined;
1626
1653
  /* functional template */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "backend-management-ui",
3
- "version": "1.7.10",
3
+ "version": "1.7.12",
4
4
  "description": "一个基于Vue+ElementUI封装的后台管理仓库,包含表格、表单、弹窗、按钮组、虚拟下拉框等常用组件",
5
5
  "author": {
6
6
  "name": "adolf3",