@truenewx/tnxvue3 3.0.13 → 3.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truenewx/tnxvue3",
3
- "version": "3.0.13",
3
+ "version": "3.0.14",
4
4
  "description": "互联网技术解决方案:Vue3扩展支持",
5
5
  "private": false,
6
6
  "type": "module",
@@ -24,7 +24,7 @@
24
24
  "vue-router": "~4.4.0"
25
25
  },
26
26
  "dependencies": {
27
- "@truenewx/tnxcore": "3.0.11",
27
+ "@truenewx/tnxcore": "3.0.12",
28
28
  "@element-plus/icons-vue": "2.3.1",
29
29
  "async-validator": "4.2.5",
30
30
  "mitt": "3.0.1"
@@ -0,0 +1,79 @@
1
+ <template>
2
+ <BAlert class="tnxbsv-alert" :model-value="modelValue" :variant="type">
3
+ <div class="d-flex">
4
+ <div class="tnxbsv-alert-icon">
5
+ <i :class="iconClass"/>
6
+ </div>
7
+ <div class="tnxbsv-alert-content">
8
+ <slot></slot>
9
+ </div>
10
+ </div>
11
+ </BAlert>
12
+ </template>
13
+
14
+ <script>
15
+ import {BAlert} from 'bootstrap-vue-next';
16
+
17
+ export default {
18
+ name: 'TnxbsvAlert',
19
+ components: {BAlert},
20
+ props: {
21
+ modelValue: {
22
+ type: Boolean,
23
+ default: true,
24
+ },
25
+ type: {
26
+ type: String,
27
+ default: 'light',
28
+ },
29
+ icon: String,
30
+ },
31
+ data() {
32
+ return {};
33
+ },
34
+ computed: {
35
+ iconClass() {
36
+ if (this.icon) {
37
+ return this.icon;
38
+ }
39
+ let iconClass = '';
40
+ switch (this.type) {
41
+ case 'success':
42
+ iconClass += 'bi-check-circle-fill text-success';
43
+ break;
44
+ case 'danger':
45
+ iconClass += 'bi-x-circle-fill text-danger';
46
+ break;
47
+ case 'warning':
48
+ iconClass += 'bi-exclamation-circle-fill text-warning';
49
+ break;
50
+ case 'light':
51
+ iconClass += 'text-secondary';
52
+ break;
53
+ default:
54
+ iconClass += 'text-' + this.type;
55
+ }
56
+ if (!iconClass.startsWith('bi-')) {
57
+ iconClass = 'bi-info-circle-fill ' + iconClass;
58
+ }
59
+ iconClass = 'bi ' + iconClass;
60
+ return iconClass;
61
+ },
62
+ },
63
+ methods: {}
64
+ }
65
+ </script>
66
+
67
+ <style>
68
+ .tnxbsv-alert-icon {
69
+ line-height: 1.3125rem;
70
+ }
71
+
72
+ .tnxbsv-alert-content {
73
+ margin-left: 0.5rem;
74
+ font-size: 0.875rem;
75
+ display: flex;
76
+ flex-direction: column;
77
+ justify-content: center;
78
+ }
79
+ </style>
@@ -218,9 +218,9 @@ export default {
218
218
  // 设置输入框为无效状态
219
219
  let fieldElement = this.queryFieldElement(fieldGroupElement);
220
220
  if (fieldElement) {
221
- // 如果字段元素或其上级元素中不包含.ignore-feedback样式,则加入.is-invalid样式
222
- if (!fieldElement.classList.contains('ignore-feedback')
223
- && !fieldElement.closest('.ignore-feedback')) {
221
+ // 如果字段元素或其上级元素中不包含.ignore-input-feedback样式,则加入.is-invalid样式
222
+ if (!fieldElement.classList.contains('ignore-input-feedback')
223
+ && !fieldElement.closest('.ignore-input-feedback')) {
224
224
  fieldElement.classList.add('is-invalid');
225
225
  }
226
226
  }
@@ -299,6 +299,13 @@ export default {
299
299
  display: block;
300
300
  }
301
301
 
302
+ .tnxbsv-form .inline-feedback .invalid-feedback {
303
+ margin-top: 0;
304
+ margin-left: 0.5rem;
305
+ width: auto;
306
+ flex-grow: 1;
307
+ }
308
+
302
309
  @media (max-width: var(--bs-breakpoint-md)) {
303
310
  .tnxbsv-form .b-form-group {
304
311
  flex-direction: column;
@@ -64,4 +64,10 @@ export default {
64
64
  flex-direction: column;
65
65
  justify-content: center;
66
66
  }
67
+
68
+ .inline-feedback .tnxbsv-form-group__content-wrapper {
69
+ flex-direction: row;
70
+ align-items: center;
71
+ justify-content: unset;
72
+ }
67
73
  </style>
@@ -6,6 +6,9 @@
6
6
  <TnxbsvButton variant="outline-primary" icon="bi bi-search" @click="query" v-if="query">
7
7
  {{ queryText }}
8
8
  </TnxbsvButton>
9
+ <TnxbsvButton @click="toReset" v-if="reset">
10
+ {{ resetText }}
11
+ </TnxbsvButton>
9
12
  </div>
10
13
  </slot>
11
14
  </TnxbsvForm>
@@ -28,14 +31,43 @@ export default {
28
31
  type: String,
29
32
  default: '查询',
30
33
  },
34
+ reset: [Boolean, Function],
35
+ resetText: {
36
+ type: String,
37
+ default: '重置',
38
+ },
31
39
  },
32
40
  data() {
33
41
  return {};
34
42
  },
35
- methods: {}
43
+ methods: {
44
+ toReset() {
45
+ if (typeof this.reset === 'function') {
46
+ this.reset();
47
+ } else if (this.reset) {
48
+ let pageSize = this.params.pageSize;
49
+ let pageNo = this.params.pageNo;
50
+ for (let key in this.params) {
51
+ delete this.params[key];
52
+ }
53
+ if (pageSize) {
54
+ this.params.pageSize = pageSize;
55
+ }
56
+ if (pageNo) {
57
+ this.params.pageNo = 1;
58
+ }
59
+ if (this.query) {
60
+ this.query();
61
+ }
62
+ }
63
+ }
64
+ }
36
65
  }
37
66
  </script>
38
67
 
39
68
  <style>
40
-
69
+ .tnxbsv-query-form-actions {
70
+ display: flex;
71
+ height: fit-content;
72
+ }
41
73
  </style>
@@ -120,7 +120,7 @@ export default {
120
120
  emits: ['update:modelValue', 'change'],
121
121
  data() {
122
122
  let model = this.getModel(this.items);
123
- if (model !== this.modelValue) {
123
+ if (this.items && model !== this.modelValue) {
124
124
  this.$emit('update:modelValue', model);
125
125
  }
126
126
  return {
@@ -10,6 +10,10 @@
10
10
  color: var(--bs-tertiary-color) !important;
11
11
  }
12
12
 
13
+ .text-placeholder {
14
+ color: var(--bs-tertiary-color);
15
+ }
16
+
13
17
  .btn-light {
14
18
  border-color: var(--bs-border-color);
15
19
  }
@@ -70,11 +74,34 @@
70
74
  cursor: pointer;
71
75
  }
72
76
 
77
+ .tnxbsv-dialog-alert,
78
+ .tnxbsv-dialog-success,
79
+ .tnxbsv-dialog-error,
73
80
  .tnxbsv-dialog-confirm {
74
81
  display: flex;
75
82
  }
76
83
 
84
+ .tnxbsv-dialog-alert i,
85
+ .tnxbsv-dialog-success i,
86
+ .tnxbsv-dialog-error i,
77
87
  .tnxbsv-dialog-confirm i {
78
- color: var(--bs-secondary-color);
88
+ font-size: 1.5rem;
89
+ line-height: 1;
79
90
  margin-right: 0.5rem;
80
91
  }
92
+
93
+ .tnxbsv-dialog-alert i {
94
+ color: var(--bs-info);
95
+ }
96
+
97
+ .tnxbsv-dialog-success i {
98
+ color: var(--bs-success);
99
+ }
100
+
101
+ .tnxbsv-dialog-error i {
102
+ color: var(--bs-danger);
103
+ }
104
+
105
+ .tnxbsv-dialog-confirm i {
106
+ color: var(--bs-secondary-color);
107
+ }
@@ -6,6 +6,7 @@ import 'bootstrap/dist/css/bootstrap.css';
6
6
  import 'bootstrap-vue-next/dist/bootstrap-vue-next.css';
7
7
  import './tnxbsv.css';
8
8
 
9
+ import Alert from './alert/Alert.vue';
9
10
  import Button from './button/Button.vue';
10
11
  import Cascader from './cascader/Cascader.vue';
11
12
  import Dialog from './dialog/Dialog.vue';
@@ -28,6 +29,7 @@ export const build = tnxvue.build;
28
29
 
29
30
  export default build('tnxbsv', () => {
30
31
  const components = Object.assign({}, tnxvue.components, {
32
+ Alert,
31
33
  Button,
32
34
  Cascader,
33
35
  Dialog,
@@ -82,6 +84,29 @@ export default build('tnxbsv', () => {
82
84
  this.hideLoading();
83
85
  this.removeToast();
84
86
  },
87
+ alert(message, title, callback, options) {
88
+ if (typeof title === 'function') {
89
+ options = callback;
90
+ callback = title;
91
+ title = '提示';
92
+ }
93
+ let buttons = tnxvue.getDefaultDialogButtons('primary', callback);
94
+ message =
95
+ `<div class="tnxbsv-dialog-alert"><i class="bi bi-exclamation-circle-fill"></i><div>${message}</div></div>`;
96
+ return this.dialog(message, title, buttons, options);
97
+ },
98
+ success(message, callback, options) {
99
+ let buttons = tnxvue.getDefaultDialogButtons('primary', callback);
100
+ message =
101
+ `<div class="tnxbsv-dialog-success"><i class="bi bi-check-circle-fill"></i><div>${message}</div></div>`;
102
+ return this.dialog(message, '成功', buttons, options);
103
+ },
104
+ error(message, callback, options) {
105
+ let buttons = tnxvue.getDefaultDialogButtons('primary', callback);
106
+ message =
107
+ `<div class="tnxbsv-dialog-error"><i class="bi bi-x-circle-fill"></i><div>${message}</div></div>`;
108
+ return this.dialog(message, '错误', buttons, options);
109
+ },
85
110
  confirm(message, title, callback, options) {
86
111
  if (typeof title === 'function') {
87
112
  options = callback;
@@ -165,6 +165,8 @@ export default {
165
165
  vm.finalDisabled = this.disabled || !vm.menu.isGranted(vm.path);
166
166
  vm.buildDropdownItems();
167
167
  });
168
+ } else {
169
+ this.finalDisabled = this.disabled;
168
170
  }
169
171
  },
170
172
  buildDropdownItems() {
@@ -262,6 +262,7 @@ export default {
262
262
  padding: 1rem;
263
263
  display: flex;
264
264
  justify-content: flex-end;
265
+ border-top: 1px solid var(--el-border-color);
265
266
  }
266
267
 
267
268
  .tnxel-dialog .el-dialog__footer .el-button {
@@ -231,7 +231,7 @@ export default {
231
231
  emits: ['update:modelValue', 'change'],
232
232
  data() {
233
233
  let model = this.getModel(this.items);
234
- if (model !== this.modelValue) {
234
+ if (this.items && model !== this.modelValue) {
235
235
  this.$emit('update:modelValue', model);
236
236
  }
237
237
  return {
@@ -608,7 +608,7 @@ el-card {
608
608
  }
609
609
 
610
610
  .el-card__header {
611
- padding: 1rem;
611
+ padding: 0.75rem 1rem;
612
612
  }
613
613
 
614
614
  .el-card__body {
@@ -276,6 +276,10 @@ export default build('tnxel', () => {
276
276
  ElMessageBox.alert(message, '错误', options).then(callback);
277
277
  this._handleZIndex('.el-message-box__wrapper:last');
278
278
  this.app.eventBus.emit('tnx.error', options);
279
+ // 打印TypeError对象,便于调试
280
+ if (typeof message === 'object' && message.name === 'TypeError') {
281
+ console.error(message);
282
+ }
279
283
  },
280
284
  confirm(message, title, callback, options) {
281
285
  if (typeof title === 'function') {
@@ -340,11 +344,16 @@ export default build('tnxel', () => {
340
344
  this._handleZIndex('.el-message:last');
341
345
  this.app.eventBus.emit('tnx.toast', options);
342
346
  },
343
- showLoading(message, options) {
347
+ showLoading(message, callback, options) {
344
348
  if (typeof message !== 'string') {
345
- options = message;
349
+ options = callback;
350
+ callback = message;
346
351
  message = undefined;
347
352
  }
353
+ if (typeof callback !== 'function') {
354
+ options = callback;
355
+ callback = undefined;
356
+ }
348
357
  options = Object.assign({
349
358
  dangerouslyUseHTMLString: true,
350
359
  }, options, {
@@ -355,6 +364,14 @@ export default build('tnxel', () => {
355
364
  window.tnx.loadingInstance = ElLoading.service(options);
356
365
  this._handleZIndex('.el-loading-mask');
357
366
  window.tnx.app.eventBus.emit('tnx.showLoading', options);
367
+ if (callback) {
368
+ let vm = window.tnx.loadingInstance.vm;
369
+ if (vm) {
370
+ this.nextTickTimeout(vm, callback, 500);
371
+ } else {
372
+ callback();
373
+ }
374
+ }
358
375
  } catch (e) {
359
376
  window.tnx.loadingInstance = null;
360
377
  console.error(e);
@@ -400,7 +417,7 @@ export default build('tnxel', () => {
400
417
  formRef.disable(false);
401
418
  }
402
419
  return result;
403
- }
420
+ },
404
421
  });
405
422
 
406
423
  tnxel.libs.ElementPlus = ElementPlus;
package/src/tnxvue.js CHANGED
@@ -108,6 +108,11 @@ export default build('tnxvue', () => {
108
108
  vm.component(component.name, component);
109
109
  }
110
110
  },
111
+ nextTickTimeout(vm, handler, timeout) {
112
+ vm.$nextTick(() => {
113
+ setTimeout(handler, timeout);
114
+ });
115
+ },
111
116
  dialog(content, title, buttons, options, contentProps) {
112
117
  // 默认不实现,由UI框架扩展层实现
113
118
  throw new Error('Unsupported function');