@truenewx/tnxvue3 3.4.4 → 3.4.5
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 +2 -2
- package/src/bootstrap-vue/dialog/Dialog.vue +22 -10
- package/src/element-plus/dialog/Dialog.vue +19 -7
- package/src/element-plus/drawer/Drawer.vue +20 -3
- package/src/element-plus/fss-upload/FssUpload.vue +1 -1
- package/src/element-plus/icon/Icon.vue +3 -0
- package/src/element-plus/tnxel.css +0 -8
- package/src/element-plus/tnxel.ts +58 -72
- package/src/tdesign/mobile/calendar/Calendar.vue +121 -0
- package/src/tdesign/mobile/date-time-picker/DateTimePicker.vue +147 -0
- package/src/tdesign/mobile/dialog/Dialog.vue +179 -0
- package/src/tdesign/mobile/dialog/DialogContent.vue +13 -0
- package/src/tdesign/mobile/drawer/Drawer.vue +176 -0
- package/src/tdesign/mobile/drawer/DrawerContent.vue +13 -0
- package/src/tdesign/mobile/enum-select/EnumSelect.vue +160 -0
- package/src/tdesign/mobile/popup/Popup.vue +106 -0
- package/src/tdesign/mobile/region-picker/RegionPicker.vue +223 -0
- package/src/tdesign/mobile/select/Select.vue +478 -0
- package/src/tdesign/mobile/slide-radio-group/SlideRadioGroup.vue +392 -0
- package/src/tdesign/mobile/tnxtdm.css +132 -0
- package/src/tdesign/mobile/tnxtdm.ts +303 -1
- package/src/tdesign/tnxtd-validator.ts +14 -13
- package/src/tdesign/tnxtd.css +66 -0
- package/src/tdesign/tnxtd.ts +4 -0
- package/src/tnxvue-router.ts +58 -5
- package/src/tnxvue.ts +20 -7
- package/tsconfig.json +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truenewx/tnxvue3",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.5",
|
|
4
4
|
"description": "互联网技术解决方案:Vue3扩展支持",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"vue-router": "~4.6.0"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@truenewx/tnxcore": "3.4.
|
|
34
|
+
"@truenewx/tnxcore": "3.4.4",
|
|
35
35
|
"bootstrap": "5.3.8",
|
|
36
36
|
"cash-dom": "8.1.5",
|
|
37
37
|
"mitt": "3.0.1"
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
<component ref="content" :is="content" v-bind="contentProps" v-else></component>
|
|
21
21
|
<template #footer>
|
|
22
22
|
<TnxbsvButton v-for="(button, index) in buttons" :key="index"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
:type="button.type || 'light'"
|
|
24
|
+
:loading="buttonLoadings[index]"
|
|
25
|
+
@click="btnClick(index)"
|
|
26
26
|
>
|
|
27
27
|
{{ button.caption || button.text }}
|
|
28
28
|
</TnxbsvButton>
|
|
@@ -113,14 +113,26 @@ export default {
|
|
|
113
113
|
},
|
|
114
114
|
btnClick(index) {
|
|
115
115
|
const button = this.buttons[index];
|
|
116
|
-
if (button
|
|
117
|
-
let
|
|
118
|
-
if (
|
|
119
|
-
this.
|
|
120
|
-
|
|
116
|
+
if (button) {
|
|
117
|
+
let click = button.click;
|
|
118
|
+
if (typeof click === 'string') {
|
|
119
|
+
if (typeof this.$refs.content[click] === 'function') {
|
|
120
|
+
click = this.$refs.content[click];
|
|
121
|
+
} else {
|
|
122
|
+
console.error(`Method '${click}' not found in component:`, this.$refs.content);
|
|
123
|
+
click = null;
|
|
124
|
+
}
|
|
121
125
|
}
|
|
122
|
-
|
|
123
|
-
|
|
126
|
+
|
|
127
|
+
if (typeof click === 'function') {
|
|
128
|
+
let result = click.call(this.$refs.content, this.close);
|
|
129
|
+
if (result === 'loading') {
|
|
130
|
+
this.buttonLoadings[index] = true;
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (result === false) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
124
136
|
}
|
|
125
137
|
}
|
|
126
138
|
this.close();
|
|
@@ -170,14 +170,26 @@ export default {
|
|
|
170
170
|
},
|
|
171
171
|
btnClick(index) {
|
|
172
172
|
const button = this.buttons[index];
|
|
173
|
-
if (button
|
|
174
|
-
let
|
|
175
|
-
if (
|
|
176
|
-
this.
|
|
177
|
-
|
|
173
|
+
if (button) {
|
|
174
|
+
let click = button.click;
|
|
175
|
+
if (typeof click === 'string') {
|
|
176
|
+
if (typeof this.$refs.content[click] === 'function') {
|
|
177
|
+
click = this.$refs.content[click];
|
|
178
|
+
} else {
|
|
179
|
+
console.error(`Method '${click}' not found in component:`, this.$refs.content);
|
|
180
|
+
click = null;
|
|
181
|
+
}
|
|
178
182
|
}
|
|
179
|
-
|
|
180
|
-
|
|
183
|
+
|
|
184
|
+
if (typeof click === 'function') {
|
|
185
|
+
let result = click.call(this.$refs.content, this.close);
|
|
186
|
+
if (result === 'loading') {
|
|
187
|
+
this.buttonLoadings[index] = true;
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
if (result === false) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
181
193
|
}
|
|
182
194
|
}
|
|
183
195
|
this.close();
|
|
@@ -87,9 +87,26 @@ export default {
|
|
|
87
87
|
methods: {
|
|
88
88
|
btnClick(index) {
|
|
89
89
|
const button = this.buttons[index];
|
|
90
|
-
if (button
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
if (button) {
|
|
91
|
+
let click = button.click;
|
|
92
|
+
if (typeof click === 'string') {
|
|
93
|
+
if (typeof this.$refs.content[click] === 'function') {
|
|
94
|
+
click = this.$refs.content[click];
|
|
95
|
+
} else {
|
|
96
|
+
console.error(`Method '${click}' not found in component:`, this.$refs.content);
|
|
97
|
+
click = null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (typeof click === 'function') {
|
|
102
|
+
let result = click.call(this.$refs.content, this.close);
|
|
103
|
+
if (result === 'loading') {
|
|
104
|
+
this.buttonLoadings[index] = true;
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (result === false) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
93
110
|
}
|
|
94
111
|
}
|
|
95
112
|
this.close();
|
|
@@ -275,7 +275,7 @@ export default {
|
|
|
275
275
|
if (typeof reject === 'function') {
|
|
276
276
|
reject(file);
|
|
277
277
|
} else {
|
|
278
|
-
this.tnx.alert('文件"' + file.name + '"还未上传完毕,请稍候').then(() => {
|
|
278
|
+
this.tnx.alert('文件"' + file.name + '"还未上传完毕,请稍候', {title: '提示'}).then(() => {
|
|
279
279
|
if (reject && typeof reject.disable === 'function') {
|
|
280
280
|
reject.disable(false);
|
|
281
281
|
}
|
|
@@ -69,6 +69,7 @@
|
|
|
69
69
|
<Switch v-else-if="value === 'Switch'"/>
|
|
70
70
|
<Tools v-else-if="value === 'Tools'"/>
|
|
71
71
|
<Top v-else-if="value === 'Top'"/>
|
|
72
|
+
<Upload v-else-if="value === 'Upload'"/>
|
|
72
73
|
<User v-else-if="value === 'User'"/>
|
|
73
74
|
<UserFilled v-else-if="value === 'UserFilled'"/>
|
|
74
75
|
<View v-else-if="value === 'View'"/>
|
|
@@ -148,6 +149,7 @@ import {
|
|
|
148
149
|
Switch,
|
|
149
150
|
Tools,
|
|
150
151
|
Top,
|
|
152
|
+
Upload,
|
|
151
153
|
User,
|
|
152
154
|
UserFilled,
|
|
153
155
|
View,
|
|
@@ -225,6 +227,7 @@ const components = {
|
|
|
225
227
|
Switch,
|
|
226
228
|
Tools,
|
|
227
229
|
Top,
|
|
230
|
+
Upload,
|
|
228
231
|
User,
|
|
229
232
|
UserFilled,
|
|
230
233
|
View,
|
|
@@ -10,14 +10,6 @@
|
|
|
10
10
|
background-color: var(--el-color-info-light-8) !important;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
.text-white {
|
|
14
|
-
color: white !important;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
.bg-white {
|
|
18
|
-
background-color: white !important;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
13
|
.text-regular {
|
|
22
14
|
color: var(--el-text-color-regular) !important;
|
|
23
15
|
}
|
|
@@ -8,6 +8,7 @@ import ElementPlus, {
|
|
|
8
8
|
ElMessageBox,
|
|
9
9
|
ElMessageBoxOptions,
|
|
10
10
|
MessageParams,
|
|
11
|
+
MessageType,
|
|
11
12
|
LoadingOptions,
|
|
12
13
|
LoadingInstance,
|
|
13
14
|
} from 'element-plus';
|
|
@@ -69,7 +70,8 @@ type VueComponent = Vue.Component & {
|
|
|
69
70
|
|
|
70
71
|
type ModalComponentInstance = Vue.ComponentPublicInstance & {
|
|
71
72
|
id: string;
|
|
72
|
-
close: () =>
|
|
73
|
+
close: () => void;
|
|
74
|
+
options: Record<string, any>;
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
export default class TnxEl extends TnxVue {
|
|
@@ -175,8 +177,8 @@ export default class TnxEl extends TnxVue {
|
|
|
175
177
|
theme: options.theme,
|
|
176
178
|
});
|
|
177
179
|
const dialog = dialogVm.mount(containerSelector) as ModalComponentInstance;
|
|
178
|
-
dialog
|
|
179
|
-
dialog
|
|
180
|
+
dialog.options = Object.assign(dialog.options || {}, options);
|
|
181
|
+
dialog.options.onClosed = this.util.function.around(dialog.options.onClosed, (onClosed: () => void): void => {
|
|
180
182
|
dialogVm.unmount();
|
|
181
183
|
this.dialogInstances.remove(dialog);
|
|
182
184
|
|
|
@@ -197,26 +199,18 @@ export default class TnxEl extends TnxVue {
|
|
|
197
199
|
return dialog;
|
|
198
200
|
}
|
|
199
201
|
|
|
200
|
-
closeDialog(all?: boolean):
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
} else {
|
|
210
|
-
break;
|
|
211
|
-
}
|
|
202
|
+
closeDialog(all?: boolean): void {
|
|
203
|
+
if (this.dialogInstances.length) {
|
|
204
|
+
let dialog = this.dialogInstances.pop();
|
|
205
|
+
while (dialog) {
|
|
206
|
+
dialog.close();
|
|
207
|
+
if (all) {
|
|
208
|
+
dialog = this.dialogInstances.pop();
|
|
209
|
+
} else {
|
|
210
|
+
break;
|
|
212
211
|
}
|
|
213
|
-
Promise.all(promises).then(() => {
|
|
214
|
-
resolve();
|
|
215
|
-
});
|
|
216
|
-
} else {
|
|
217
|
-
resolve();
|
|
218
212
|
}
|
|
219
|
-
}
|
|
213
|
+
}
|
|
220
214
|
}
|
|
221
215
|
|
|
222
216
|
private drawerInstances: ModalComponentInstance[] = []; // 抽屉实例堆栈
|
|
@@ -251,8 +245,8 @@ export default class TnxEl extends TnxVue {
|
|
|
251
245
|
theme: options.theme,
|
|
252
246
|
});
|
|
253
247
|
const drawer = drawerVm.mount(containerSelector) as ModalComponentInstance;
|
|
254
|
-
drawer
|
|
255
|
-
drawer
|
|
248
|
+
drawer.options = Object.assign(drawer.options || {}, options);
|
|
249
|
+
drawer.options.onClosed = this.util.function.around(drawer.options.onClosed, (onClosed: () => void): void => {
|
|
256
250
|
drawerVm.unmount();
|
|
257
251
|
this.drawerInstances.remove(drawer);
|
|
258
252
|
|
|
@@ -273,26 +267,18 @@ export default class TnxEl extends TnxVue {
|
|
|
273
267
|
return drawer;
|
|
274
268
|
}
|
|
275
269
|
|
|
276
|
-
closeDrawer(all?: boolean):
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
} else {
|
|
286
|
-
break;
|
|
287
|
-
}
|
|
270
|
+
closeDrawer(all?: boolean): void {
|
|
271
|
+
if (this.drawerInstances.length) {
|
|
272
|
+
let drawer = this.drawerInstances.pop();
|
|
273
|
+
while (drawer) {
|
|
274
|
+
drawer.close();
|
|
275
|
+
if (all) {
|
|
276
|
+
drawer = this.drawerInstances.pop();
|
|
277
|
+
} else {
|
|
278
|
+
break;
|
|
288
279
|
}
|
|
289
|
-
Promise.all(promises).then(() => {
|
|
290
|
-
resolve();
|
|
291
|
-
});
|
|
292
|
-
} else {
|
|
293
|
-
resolve();
|
|
294
280
|
}
|
|
295
|
-
}
|
|
281
|
+
}
|
|
296
282
|
}
|
|
297
283
|
|
|
298
284
|
private closeMessage() {
|
|
@@ -322,73 +308,73 @@ export default class TnxEl extends TnxVue {
|
|
|
322
308
|
});
|
|
323
309
|
}
|
|
324
310
|
|
|
325
|
-
toast(message: string,
|
|
311
|
+
toast(message: string, theme?: string, options?: { duration?: number }): Promise<void> {
|
|
326
312
|
this.closeMessage();
|
|
327
313
|
return new Promise<void>((resolve) => {
|
|
328
|
-
let
|
|
329
|
-
type: 'success', // 默认为成功主题,可更改为其它主题
|
|
314
|
+
let msgParams: MessageParams = {
|
|
315
|
+
type: (theme || 'success') as MessageType, // 默认为成功主题,可更改为其它主题
|
|
330
316
|
offset: this.util.dom.getDocHeight() * 0.4,
|
|
331
317
|
dangerouslyUseHTMLString: true,
|
|
332
318
|
showClose: false,
|
|
333
319
|
message: message,
|
|
334
|
-
duration:
|
|
320
|
+
duration: options?.duration || 2000,
|
|
335
321
|
customClass: 'tnxel-toast',
|
|
336
322
|
onClose: () => {
|
|
337
323
|
resolve();
|
|
338
324
|
}
|
|
339
325
|
};
|
|
340
|
-
ElMessage(
|
|
326
|
+
ElMessage(msgParams);
|
|
341
327
|
this.handleZIndex('.el-message:last');
|
|
342
|
-
this.eventBus.emit('tnx.toast',
|
|
328
|
+
this.eventBus.emit('tnx.toast', msgParams);
|
|
343
329
|
});
|
|
344
330
|
}
|
|
345
331
|
|
|
346
|
-
async alert(message: string, title
|
|
347
|
-
let
|
|
348
|
-
title: title,
|
|
332
|
+
async alert(message: string, options?: { title?: string, confirmButtonText?: string }): Promise<void> {
|
|
333
|
+
let msgOptions: ElMessageBoxOptions = {
|
|
334
|
+
title: options?.title || '提示',
|
|
349
335
|
dangerouslyUseHTMLString: true,
|
|
350
336
|
type: 'warning',
|
|
351
|
-
confirmButtonText: '确定',
|
|
337
|
+
confirmButtonText: options?.confirmButtonText || '确定',
|
|
352
338
|
};
|
|
353
339
|
this.closeMessage();
|
|
354
|
-
await ElMessageBox.alert(message,
|
|
340
|
+
await ElMessageBox.alert(message, msgOptions);
|
|
355
341
|
this.handleZIndex('.el-message-box__wrapper:last');
|
|
356
|
-
this.eventBus.emit('tnx.alert', Object.assign({},
|
|
342
|
+
this.eventBus.emit('tnx.alert', Object.assign({}, msgOptions, {message}));
|
|
357
343
|
}
|
|
358
344
|
|
|
359
|
-
async success(message: string): Promise<void> {
|
|
360
|
-
let
|
|
361
|
-
title: '成功',
|
|
345
|
+
async success(message: string, options?: { title?: string, confirmButtonText?: string }): Promise<void> {
|
|
346
|
+
let msgOptions: ElMessageBoxOptions = {
|
|
347
|
+
title: options?.title || '成功',
|
|
362
348
|
dangerouslyUseHTMLString: true,
|
|
363
349
|
type: 'success',
|
|
364
|
-
confirmButtonText: '确定',
|
|
350
|
+
confirmButtonText: options?.confirmButtonText || '确定',
|
|
365
351
|
};
|
|
366
352
|
this.closeMessage();
|
|
367
|
-
await ElMessageBox.alert(message,
|
|
353
|
+
await ElMessageBox.alert(message, msgOptions);
|
|
368
354
|
this.handleZIndex('.el-message-box__wrapper:last');
|
|
369
|
-
this.eventBus.emit('tnx.success', Object.assign({},
|
|
355
|
+
this.eventBus.emit('tnx.success', Object.assign({}, msgOptions, {message}));
|
|
370
356
|
}
|
|
371
357
|
|
|
372
|
-
async error(message: string): Promise<void> {
|
|
373
|
-
let
|
|
374
|
-
title: '错误',
|
|
358
|
+
async error(message: string, options?: { title?: string, confirmButtonText?: string }): Promise<void> {
|
|
359
|
+
let msgOptions: ElMessageBoxOptions = {
|
|
360
|
+
title: options?.title || '错误',
|
|
375
361
|
dangerouslyUseHTMLString: true,
|
|
376
362
|
type: 'error',
|
|
377
|
-
confirmButtonText: '确定',
|
|
363
|
+
confirmButtonText: options?.confirmButtonText || '确定',
|
|
378
364
|
};
|
|
379
365
|
this.closeMessage();
|
|
380
|
-
await ElMessageBox.alert(message,
|
|
366
|
+
await ElMessageBox.alert(message, msgOptions);
|
|
381
367
|
this.handleZIndex('.el-message-box__wrapper:last');
|
|
382
|
-
this.eventBus.emit('tnx.error', Object.assign({},
|
|
368
|
+
this.eventBus.emit('tnx.error', Object.assign({}, msgOptions, {message}));
|
|
383
369
|
}
|
|
384
370
|
|
|
385
|
-
confirm(message: string, title
|
|
386
|
-
let
|
|
387
|
-
title: title,
|
|
371
|
+
confirm(message: string, options?: { title?: string, confirmButtonText?: string, cancelButtonText?: string }) {
|
|
372
|
+
let msgOptions: ElMessageBoxOptions = {
|
|
373
|
+
title: options?.title || '确认',
|
|
388
374
|
type: 'info',
|
|
389
375
|
icon: Vue.markRaw(Icon.components.QuestionFilled),
|
|
390
|
-
confirmButtonText: '确定',
|
|
391
|
-
cancelButtonText: '取消',
|
|
376
|
+
confirmButtonText: options?.confirmButtonText || '确定',
|
|
377
|
+
cancelButtonText: options?.cancelButtonText || '取消',
|
|
392
378
|
dangerouslyUseHTMLString: true,
|
|
393
379
|
distinguishCancelAndClose: true,
|
|
394
380
|
};
|
|
@@ -401,13 +387,13 @@ export default class TnxEl extends TnxVue {
|
|
|
401
387
|
|
|
402
388
|
this.closeMessage();
|
|
403
389
|
return new Promise<boolean>(resolve => {
|
|
404
|
-
ElMessageBox.confirm(message,
|
|
390
|
+
ElMessageBox.confirm(message, msgOptions).then(() => {
|
|
405
391
|
resolve(true);
|
|
406
392
|
}).catch(() => {
|
|
407
393
|
resolve(false);
|
|
408
394
|
});
|
|
409
395
|
this.handleZIndex('.el-message-box__wrapper:last');
|
|
410
|
-
this.eventBus.emit('tnx.confirm', Object.assign({},
|
|
396
|
+
this.eventBus.emit('tnx.confirm', Object.assign({}, msgOptions, {message}));
|
|
411
397
|
})
|
|
412
398
|
}
|
|
413
399
|
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="tnxtdm-calendar">
|
|
3
|
+
<div class="tnxtdm-calendar__value">{{ modelValue }}</div>
|
|
4
|
+
<div class="tnxtdm-calendar__icon" :style="{color: iconColor}" @click="visible = true">
|
|
5
|
+
<t-icon name="calendar-1"/>
|
|
6
|
+
</div>
|
|
7
|
+
<t-calendar
|
|
8
|
+
v-model:visible="visible"
|
|
9
|
+
:value="calendarValue"
|
|
10
|
+
type="single"
|
|
11
|
+
switch-mode="year-month"
|
|
12
|
+
:min-date="finalMinDate"
|
|
13
|
+
:max-date="finalMaxDate"
|
|
14
|
+
:title="title"
|
|
15
|
+
@confirm="confirm"
|
|
16
|
+
/>
|
|
17
|
+
</div>
|
|
18
|
+
</template>
|
|
19
|
+
|
|
20
|
+
<script>
|
|
21
|
+
const pattern = 'yyyy-MM-dd';
|
|
22
|
+
|
|
23
|
+
function parseDate(val) {
|
|
24
|
+
if (!val) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
if (val instanceof Date) {
|
|
28
|
+
return val;
|
|
29
|
+
}
|
|
30
|
+
if (typeof val === 'number') {
|
|
31
|
+
return new Date(val);
|
|
32
|
+
}
|
|
33
|
+
if (typeof val === 'string') {
|
|
34
|
+
val = val.replace(/-/g, '/');
|
|
35
|
+
}
|
|
36
|
+
const d = new Date(val);
|
|
37
|
+
if (!isNaN(d.getTime())) {
|
|
38
|
+
return d;
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export default {
|
|
44
|
+
name: 'TnxtdmCalendar',
|
|
45
|
+
props: {
|
|
46
|
+
modelValue: String,
|
|
47
|
+
title: String,
|
|
48
|
+
defaultValue: {
|
|
49
|
+
type: String,
|
|
50
|
+
default: () => {
|
|
51
|
+
return new Date().format(pattern);
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
minDate: {
|
|
55
|
+
type: [String, Number, Date],
|
|
56
|
+
default: '1900-01-01',
|
|
57
|
+
},
|
|
58
|
+
maxDate: {
|
|
59
|
+
type: [String, Number, Date],
|
|
60
|
+
default: '2099-12-31',
|
|
61
|
+
},
|
|
62
|
+
iconColor: String,
|
|
63
|
+
},
|
|
64
|
+
data() {
|
|
65
|
+
return {
|
|
66
|
+
visible: false,
|
|
67
|
+
calendarValue: parseDate(this.modelValue || this.defaultValue),
|
|
68
|
+
};
|
|
69
|
+
},
|
|
70
|
+
computed: {
|
|
71
|
+
finalMinDate() {
|
|
72
|
+
return parseDate(this.minDate);
|
|
73
|
+
},
|
|
74
|
+
finalMaxDate() {
|
|
75
|
+
return parseDate(this.maxDate);
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
emits: ['update:modelValue'],
|
|
79
|
+
watch: {
|
|
80
|
+
modelValue() {
|
|
81
|
+
this.init();
|
|
82
|
+
},
|
|
83
|
+
visible(val) {
|
|
84
|
+
if (val) {
|
|
85
|
+
this.init();
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
mounted() {
|
|
90
|
+
this.init();
|
|
91
|
+
},
|
|
92
|
+
methods: {
|
|
93
|
+
init() {
|
|
94
|
+
let value = this.modelValue || this.defaultValue;
|
|
95
|
+
this.calendarValue = parseDate(value);
|
|
96
|
+
},
|
|
97
|
+
confirm(val) {
|
|
98
|
+
let result = new Date(val).format(pattern);
|
|
99
|
+
this.$emit('update:modelValue', result);
|
|
100
|
+
this.visible = false;
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
</script>
|
|
105
|
+
|
|
106
|
+
<style>
|
|
107
|
+
.tnxtdm-calendar {
|
|
108
|
+
display: flex;
|
|
109
|
+
align-items: center;
|
|
110
|
+
|
|
111
|
+
.tnxtdm-calendar__value {
|
|
112
|
+
min-width: 95px;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.tnxtdm-calendar__icon {
|
|
116
|
+
display: flex;
|
|
117
|
+
align-items: center;
|
|
118
|
+
color: var(--td-text-color-primary);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
</style>
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="tnxtdm-date-time-picker">
|
|
3
|
+
<div class="tnxtdm-date-time-picker__value" :data-mode="mode">{{ model }}</div>
|
|
4
|
+
<div class="tnxtdm-date-time-picker__icon" :style="{color: iconColor}" @click="visible = true">
|
|
5
|
+
<t-icon name="calendar-1"/>
|
|
6
|
+
</div>
|
|
7
|
+
<t-popup v-model="visible" placement="bottom">
|
|
8
|
+
<t-date-time-picker
|
|
9
|
+
v-model="pickerValue"
|
|
10
|
+
:format="format"
|
|
11
|
+
:mode="mode"
|
|
12
|
+
:title="title"
|
|
13
|
+
:start="getDateValue(start)"
|
|
14
|
+
:end="getDateValue(end)"
|
|
15
|
+
@confirm="confirm"
|
|
16
|
+
@cancel="visible = false"
|
|
17
|
+
v-if="visible"/>
|
|
18
|
+
</t-popup>
|
|
19
|
+
</div>
|
|
20
|
+
</template>
|
|
21
|
+
|
|
22
|
+
<script>
|
|
23
|
+
export default {
|
|
24
|
+
name: 'TnxtdmDateTimePicker',
|
|
25
|
+
props: {
|
|
26
|
+
modelValue: String,
|
|
27
|
+
title: String,
|
|
28
|
+
defaultValue: {
|
|
29
|
+
type: [String, Number],
|
|
30
|
+
default: () => {
|
|
31
|
+
return new Date().getTime();
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
mode: {
|
|
35
|
+
type: String,
|
|
36
|
+
default: 'date',
|
|
37
|
+
},
|
|
38
|
+
showCellTitle: Boolean,
|
|
39
|
+
start: {
|
|
40
|
+
type: [String, Number],
|
|
41
|
+
default: '1000-01-01 00:00:00',
|
|
42
|
+
},
|
|
43
|
+
end: {
|
|
44
|
+
type: [String, Number],
|
|
45
|
+
default: '9999-12-31 23:59:59',
|
|
46
|
+
},
|
|
47
|
+
iconColor: String,
|
|
48
|
+
},
|
|
49
|
+
data() {
|
|
50
|
+
return {
|
|
51
|
+
visible: false,
|
|
52
|
+
model: this.modelValue || '',
|
|
53
|
+
pickerValue: '',
|
|
54
|
+
};
|
|
55
|
+
},
|
|
56
|
+
computed: {
|
|
57
|
+
format() {
|
|
58
|
+
switch (this.mode) {
|
|
59
|
+
case 'year':
|
|
60
|
+
return 'YYYY';
|
|
61
|
+
case 'month':
|
|
62
|
+
return 'YYYY-MM';
|
|
63
|
+
case 'date':
|
|
64
|
+
return 'YYYY-MM-DD';
|
|
65
|
+
case 'hour':
|
|
66
|
+
return 'YYYY-MM-DD HH';
|
|
67
|
+
case 'minute':
|
|
68
|
+
return 'YYYY-MM-DD HH:mm';
|
|
69
|
+
case 'second':
|
|
70
|
+
return 'YYYY-MM-DD HH:mm:ss';
|
|
71
|
+
}
|
|
72
|
+
return undefined;
|
|
73
|
+
},
|
|
74
|
+
pattern() {
|
|
75
|
+
return this.format.replace('YYYY', 'yyyy').replace('DD', 'dd');
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
emits: ['update:modelValue'],
|
|
79
|
+
watch: {
|
|
80
|
+
modelValue(val) {
|
|
81
|
+
this.model = val;
|
|
82
|
+
},
|
|
83
|
+
model(val) {
|
|
84
|
+
this.$emit('update:modelValue', val);
|
|
85
|
+
},
|
|
86
|
+
visible(val) {
|
|
87
|
+
if (val) {
|
|
88
|
+
this.pickerValue = this.model || this.getDateValue(this.defaultValue);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
methods: {
|
|
93
|
+
getDateValue(date) {
|
|
94
|
+
if (date) {
|
|
95
|
+
return new Date(date).format(this.pattern);
|
|
96
|
+
}
|
|
97
|
+
return undefined;
|
|
98
|
+
},
|
|
99
|
+
confirm(value) {
|
|
100
|
+
this.model = String(value);
|
|
101
|
+
this.visible = false;
|
|
102
|
+
},
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
</script>
|
|
106
|
+
|
|
107
|
+
<style>
|
|
108
|
+
.tnxtdm-date-time-picker {
|
|
109
|
+
display: flex;
|
|
110
|
+
align-items: center;
|
|
111
|
+
|
|
112
|
+
.tnxtdm-date-time-picker__value {
|
|
113
|
+
display: flex;
|
|
114
|
+
align-items: center;
|
|
115
|
+
|
|
116
|
+
&[data-mode="year"] {
|
|
117
|
+
min-width: 44px;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
&[data-mode="month"] {
|
|
121
|
+
min-width: 70px;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
&[data-mode="date"] {
|
|
125
|
+
min-width: 95px;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
&[data-mode="hour"] {
|
|
129
|
+
min-width: 119px;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
&[data-mode="minute"] {
|
|
133
|
+
min-width: 141px;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
&[data-mode="second"] {
|
|
137
|
+
min-width: 164px;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.tnxtdm-date-time-picker__icon {
|
|
142
|
+
display: flex;
|
|
143
|
+
align-items: center;
|
|
144
|
+
color: var(--td-text-color-primary);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
</style>
|