uview-plus 3.4.19 → 3.4.22
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/changelog.md +26 -0
- package/components/u-datetime-picker/props.js +5 -1
- package/components/u-datetime-picker/u-datetime-picker.vue +1 -1
- package/components/u-float-button/u-float-button.vue +1 -1
- package/components/u-navbar-mini/u-navbar-mini.vue +0 -1
- package/components/u-select/u-select.vue +6 -1
- package/components/u-status-bar/props.js +6 -1
- package/components/u-status-bar/statusBar.js +2 -1
- package/components/u-status-bar/u-status-bar.vue +2 -0
- package/components/u-subsection/u-subsection.vue +3 -2
- package/components/u-tag/u-tag.vue +22 -8
- package/components/u-toolbar/toolbar.js +1 -1
- package/components/u-toolbar/u-toolbar.vue +1 -0
- package/components/u-upload/props.js +5 -0
- package/components/u-upload/u-upload.vue +68 -21
- package/components/u-upload/upload.js +2 -1
- package/components/u-upload/utils.js +5 -0
- package/index.js +13 -10
- package/package.json +1 -1
package/changelog.md
CHANGED
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
## 3.4.22(2025-04-22)
|
|
2
|
+
fix: 修复自动上传偶发的success被覆盖为uploading
|
|
3
|
+
|
|
4
|
+
fix: float-button缺少key #677
|
|
5
|
+
|
|
6
|
+
fix: upload组件完善优化(感谢@semdy)
|
|
7
|
+
|
|
8
|
+
fix: toolbar组件confirmColor属性默认改为空,以便默认使用主题色、标题字体加粗(感谢@semdy)
|
|
9
|
+
|
|
10
|
+
## 3.4.21(2025-04-21)
|
|
11
|
+
feat: subsection分段器支持双向绑定current
|
|
12
|
+
|
|
13
|
+
feat: select组件支持maxHeight属性
|
|
14
|
+
|
|
15
|
+
feat: datetime-picker支持inputBorder属性
|
|
16
|
+
|
|
17
|
+
## 3.4.20(2025-04-17)
|
|
18
|
+
fix: 修复navbar-mini提示border不存在
|
|
19
|
+
|
|
20
|
+
feat: status-bar支持对外暴露状态栏高度值
|
|
21
|
+
|
|
22
|
+
feat: upload支持自定义自动上传后处理逻辑便于对接不同规范后端
|
|
23
|
+
|
|
24
|
+
feat: 优化tag组件插槽
|
|
25
|
+
|
|
26
|
+
|
|
1
27
|
## 3.4.19(2025-04-14)
|
|
2
28
|
fix: 修复model组件增加contentStyle带来的语法问题
|
|
3
29
|
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
bottom: height
|
|
26
26
|
}">
|
|
27
27
|
<slot name="list">
|
|
28
|
-
<template v-for="item in list">
|
|
28
|
+
<template :key="index" v-for="(item, index) in list">
|
|
29
29
|
<view class="u-float-button__item" :style="{
|
|
30
30
|
backgroundColor: item?.backgroundColor ? item?.backgroundColor : backgroundColor,
|
|
31
31
|
color: item?.color ? item?.color : color,
|
|
@@ -22,9 +22,10 @@
|
|
|
22
22
|
:duration="duration + 50"
|
|
23
23
|
:customStyle="overlayStyle"
|
|
24
24
|
:opacity="overlayOpacity"
|
|
25
|
+
@touchmove.stop.prevent="noop"
|
|
25
26
|
></u-overlay>
|
|
26
27
|
<view class="u-select__options__wrap"
|
|
27
|
-
:style="{ zIndex: zIndex + 1, left: optionsWrapLeft, right: optionsWrapRight }">
|
|
28
|
+
:style="{ overflowY: 'auto', zIndex: zIndex + 1, left: optionsWrapLeft, right: optionsWrapRight, maxHeight: maxHeight}">
|
|
28
29
|
<view class="u-select__options" v-if="isOpen">
|
|
29
30
|
<slot name="options">
|
|
30
31
|
<view class="u-select__options_item"
|
|
@@ -50,6 +51,10 @@ export default {
|
|
|
50
51
|
name:"up-select",
|
|
51
52
|
emits: ['update:current', 'select'],
|
|
52
53
|
props: {
|
|
54
|
+
maxHeight: {
|
|
55
|
+
type: String,
|
|
56
|
+
default: '90vh'
|
|
57
|
+
},
|
|
53
58
|
overlay: {
|
|
54
59
|
type: Boolean,
|
|
55
60
|
default: true
|
|
@@ -34,11 +34,13 @@
|
|
|
34
34
|
this.isH5 = true
|
|
35
35
|
// #endif
|
|
36
36
|
},
|
|
37
|
+
emits: ['update:height'],
|
|
37
38
|
computed: {
|
|
38
39
|
style() {
|
|
39
40
|
const style = {}
|
|
40
41
|
// 状态栏高度,由于某些安卓和微信开发工具无法识别css的顶部状态栏变量,所以使用js获取的方式
|
|
41
42
|
let sheight = getWindowInfo().statusBarHeight
|
|
43
|
+
this.$emit('update:height', sheight)
|
|
42
44
|
if (sheight == 0) {
|
|
43
45
|
this.isH5 = true
|
|
44
46
|
} else {
|
|
@@ -189,7 +189,7 @@ export default {
|
|
|
189
189
|
beforeUnmount() {
|
|
190
190
|
uni.offWindowResize(this.windowResizeCallback)
|
|
191
191
|
},
|
|
192
|
-
emits: ["change"],
|
|
192
|
+
emits: ["change", "update:current"],
|
|
193
193
|
methods: {
|
|
194
194
|
addStyle,
|
|
195
195
|
init() {
|
|
@@ -217,7 +217,8 @@ export default {
|
|
|
217
217
|
// #endif
|
|
218
218
|
},
|
|
219
219
|
clickHandler(index) {
|
|
220
|
-
this.innerCurrent = index
|
|
220
|
+
this.innerCurrent = index;
|
|
221
|
+
this.$emit('update:current', index);
|
|
221
222
|
this.$emit("change", index);
|
|
222
223
|
},
|
|
223
224
|
},
|
|
@@ -32,15 +32,29 @@
|
|
|
32
32
|
></u-icon>
|
|
33
33
|
</view>
|
|
34
34
|
</slot>
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
:style="[textColor]"
|
|
38
|
-
:class="[`u-tag__text--${type}`, plain && `u-tag__text--${type}--plain`, `u-tag__text--${size}`]"
|
|
39
|
-
>
|
|
40
|
-
<slot>
|
|
41
|
-
{{ text }}
|
|
35
|
+
<view class="u-tag__content">
|
|
36
|
+
<slot name="content">
|
|
42
37
|
</slot>
|
|
43
|
-
|
|
38
|
+
<template v-if="!$slots.content">
|
|
39
|
+
<text
|
|
40
|
+
v-if="!$slots.default && !$slots.$default"
|
|
41
|
+
class="u-tag__text"
|
|
42
|
+
:style="[textColor]"
|
|
43
|
+
:class="[`u-tag__text--${type}`, plain && `u-tag__text--${type}--plain`, `u-tag__text--${size}`]"
|
|
44
|
+
>
|
|
45
|
+
{{ text }}
|
|
46
|
+
</text>
|
|
47
|
+
<text
|
|
48
|
+
v-else
|
|
49
|
+
class="u-tag__text"
|
|
50
|
+
:style="[textColor]"
|
|
51
|
+
:class="[`u-tag__text--${type}`, plain && `u-tag__text--${type}--plain`, `u-tag__text--${size}`]"
|
|
52
|
+
>
|
|
53
|
+
<slot>
|
|
54
|
+
</slot>
|
|
55
|
+
</text>
|
|
56
|
+
</template>
|
|
57
|
+
</view>
|
|
44
58
|
</view>
|
|
45
59
|
<view
|
|
46
60
|
class="u-tag__close"
|
|
@@ -163,5 +163,10 @@ export const props = defineMixin({
|
|
|
163
163
|
type: Boolean,
|
|
164
164
|
default: () => defProps.upload.getVideoThumb
|
|
165
165
|
},
|
|
166
|
+
// 自定义自动上传后处理
|
|
167
|
+
customAfterAutoUpload: {
|
|
168
|
+
type: Boolean,
|
|
169
|
+
default: () => defProps.upload.customAfterAutoUpload
|
|
170
|
+
},
|
|
166
171
|
}
|
|
167
172
|
})
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
v-else
|
|
40
40
|
color="#80CBF9"
|
|
41
41
|
size="26"
|
|
42
|
-
:name="item.isVideo || (item.type && item.type === 'video') ? 'movie' : '
|
|
42
|
+
:name="item.isVideo || (item.type && item.type === 'video') ? 'movie' : 'file-text'"
|
|
43
43
|
></u-icon>
|
|
44
44
|
<view v-if="item.status === 'success'"
|
|
45
45
|
class="u-upload__wrap__play"
|
|
@@ -54,6 +54,10 @@
|
|
|
54
54
|
v-else
|
|
55
55
|
class="u-upload__wrap__preview__other"
|
|
56
56
|
@tap="onClickPreview(item, index)"
|
|
57
|
+
:style="[{
|
|
58
|
+
width: addUnit(width),
|
|
59
|
+
height: addUnit(height)
|
|
60
|
+
}]"
|
|
57
61
|
>
|
|
58
62
|
<u-icon
|
|
59
63
|
color="#80CBF9"
|
|
@@ -61,7 +65,7 @@
|
|
|
61
65
|
:name="item.isVideo || (item.type && item.type === 'video') ? 'movie' : 'folder'"
|
|
62
66
|
></u-icon>
|
|
63
67
|
<text class="u-upload__wrap__preview__other__text">
|
|
64
|
-
{{item.isVideo || (item.type && item.type === 'video') ? '视频' : '文件'}}
|
|
68
|
+
{{item.isVideo || (item.type && item.type === 'video') ? item.name || '视频' : item.name || '文件'}}
|
|
65
69
|
</text>
|
|
66
70
|
</view>
|
|
67
71
|
<view
|
|
@@ -78,7 +82,6 @@
|
|
|
78
82
|
<u-loading-icon
|
|
79
83
|
size="22"
|
|
80
84
|
mode="circle"
|
|
81
|
-
color="#ffffff"
|
|
82
85
|
v-else
|
|
83
86
|
/>
|
|
84
87
|
</view>
|
|
@@ -263,7 +266,7 @@
|
|
|
263
266
|
}
|
|
264
267
|
},
|
|
265
268
|
// #ifdef VUE3
|
|
266
|
-
emits: ['error', 'beforeRead', 'oversize', 'afterRead', 'delete', 'clickPreview', 'update:fileList'],
|
|
269
|
+
emits: ['error', 'beforeRead', 'oversize', 'afterRead', 'delete', 'clickPreview', 'update:fileList', 'afterAutoUpload'],
|
|
267
270
|
// #endif
|
|
268
271
|
methods: {
|
|
269
272
|
addUnit,
|
|
@@ -327,18 +330,19 @@
|
|
|
327
330
|
const {
|
|
328
331
|
fileList = [], maxCount
|
|
329
332
|
} = this;
|
|
330
|
-
const lists = fileList.map((item) =>
|
|
331
|
-
|
|
333
|
+
const lists = fileList.map((item) => {
|
|
334
|
+
const name = item.name || item.url || item.thumb
|
|
335
|
+
return Object.assign(Object.assign({}, item), {
|
|
332
336
|
// 如果item.url为本地选择的blob文件的话,无法判断其为video还是image,此处优先通过accept做判断处理
|
|
333
|
-
isImage: this.accept === 'image' || test.image(
|
|
334
|
-
isVideo: this.accept === 'video' || test.video(
|
|
335
|
-
deletable: typeof
|
|
337
|
+
isImage: name ? test.image(name) : (this.accept === 'image' || test.image(name)),
|
|
338
|
+
isVideo: name ? test.video(name) : (this.accept === 'video' || test.video(name)),
|
|
339
|
+
deletable: typeof item.deletable === 'boolean' ? item.deletable : this.deletable,
|
|
336
340
|
})
|
|
337
|
-
);
|
|
341
|
+
});
|
|
338
342
|
this.lists = lists
|
|
339
343
|
this.isInCount = lists.length < maxCount
|
|
340
344
|
},
|
|
341
|
-
chooseFile() {
|
|
345
|
+
chooseFile(params) {
|
|
342
346
|
const {
|
|
343
347
|
maxCount,
|
|
344
348
|
multiple,
|
|
@@ -358,13 +362,14 @@
|
|
|
358
362
|
accept: this.accept,
|
|
359
363
|
extension: this.extension,
|
|
360
364
|
multiple: this.multiple,
|
|
361
|
-
capture: capture,
|
|
365
|
+
capture: this.capture,
|
|
362
366
|
compressed: this.compressed,
|
|
363
367
|
maxDuration: this.maxDuration,
|
|
364
368
|
sizeType: this.sizeType,
|
|
365
369
|
camera: this.camera,
|
|
366
370
|
}, {
|
|
367
371
|
maxCount: maxCount - lists.length,
|
|
372
|
+
...params
|
|
368
373
|
})
|
|
369
374
|
)
|
|
370
375
|
.then((res) => {
|
|
@@ -406,7 +411,7 @@
|
|
|
406
411
|
if (test.promise(res)) {
|
|
407
412
|
res.then((data) => this.onAfterRead(data || file));
|
|
408
413
|
} else {
|
|
409
|
-
this.onAfterRead(
|
|
414
|
+
this.onAfterRead(res);
|
|
410
415
|
}
|
|
411
416
|
},
|
|
412
417
|
getDetail(index) {
|
|
@@ -491,12 +496,29 @@
|
|
|
491
496
|
// header: header,
|
|
492
497
|
formData: formData,
|
|
493
498
|
success: (uploadFileRes) => {
|
|
494
|
-
result = res0.data.params.host + '/' + res0.data.params.key;
|
|
495
499
|
let thumb = '';
|
|
496
|
-
|
|
497
|
-
|
|
500
|
+
let afterPromise = '';
|
|
501
|
+
if (that.customAfterAutoUpload) {
|
|
502
|
+
afterPromise = new Promise((resolve, reject) => {
|
|
503
|
+
that.$emit(
|
|
504
|
+
'afterAutoUpload',
|
|
505
|
+
Object.assign(res0, {
|
|
506
|
+
callback: (r) => {
|
|
507
|
+
r.url ? resolve(r) : reject();
|
|
508
|
+
},
|
|
509
|
+
})
|
|
510
|
+
);
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
if (test.promise(afterPromise)) {
|
|
514
|
+
afterPromise.then((data) => that.succcessUpload(len + j, data.url, data.thumb));
|
|
515
|
+
} else {
|
|
516
|
+
result = res0.data.params.host + '/' + res0.data.params.key;
|
|
517
|
+
if (that.accept === 'video' || test.video(result)) {
|
|
518
|
+
thumb = result + '?x-oss-process=video/snapshot,t_10000,m_fast';
|
|
519
|
+
}
|
|
520
|
+
that.succcessUpload(len + j, result, thumb);
|
|
498
521
|
}
|
|
499
|
-
that.succcessUpload(len + j, result, thumb);
|
|
500
522
|
}
|
|
501
523
|
});
|
|
502
524
|
uploadTask.onProgressUpdate((res) => {
|
|
@@ -517,9 +539,33 @@
|
|
|
517
539
|
name: 'file',
|
|
518
540
|
// fileType: 'video', // 仅支付宝小程序,且必填。
|
|
519
541
|
header: this.autoUploadHeader,
|
|
520
|
-
success: (
|
|
521
|
-
|
|
522
|
-
|
|
542
|
+
success: (uploadFileRes) => {
|
|
543
|
+
let res0 = uploadFileRes.data;
|
|
544
|
+
let afterPromise = '';
|
|
545
|
+
if (that.customAfterAutoUpload) {
|
|
546
|
+
afterPromise = new Promise((resolve, reject) => {
|
|
547
|
+
that.$emit(
|
|
548
|
+
'afterAutoUpload',
|
|
549
|
+
Object.assign(res0, {
|
|
550
|
+
callback: (r) => {
|
|
551
|
+
r.url ? resolve(r) : reject();
|
|
552
|
+
}
|
|
553
|
+
})
|
|
554
|
+
);
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
if (test.promise(afterPromise)) {
|
|
558
|
+
afterPromise.then((data) => that.succcessUpload(len + j, data.url));
|
|
559
|
+
} else {
|
|
560
|
+
if (res0.code != 200) {
|
|
561
|
+
uni.showToast({
|
|
562
|
+
title: res0.msg
|
|
563
|
+
});
|
|
564
|
+
} else {
|
|
565
|
+
result = res0.data.url;
|
|
566
|
+
that.succcessUpload(len + j, result);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
523
569
|
}
|
|
524
570
|
});
|
|
525
571
|
uploadTask.onProgressUpdate((res) => {
|
|
@@ -546,7 +592,8 @@
|
|
|
546
592
|
let item = this.fileList[index];
|
|
547
593
|
this.fileList.splice(index, 1, {
|
|
548
594
|
...item,
|
|
549
|
-
|
|
595
|
+
// 注意这里不判断会出现succcessUpload先执行又被覆盖的问题
|
|
596
|
+
status: param.progress == 100 ? 'success' : 'uploading',
|
|
550
597
|
message: '',
|
|
551
598
|
progress: param.progress
|
|
552
599
|
});
|
|
@@ -89,6 +89,11 @@ export function chooseFile({
|
|
|
89
89
|
maxCount,
|
|
90
90
|
extension
|
|
91
91
|
}) {
|
|
92
|
+
try {
|
|
93
|
+
capture = test.array(capture) ? capture : capture.split(',');
|
|
94
|
+
} catch(e) {
|
|
95
|
+
capture = [];
|
|
96
|
+
}
|
|
92
97
|
return new Promise((resolve, reject) => {
|
|
93
98
|
switch (accept) {
|
|
94
99
|
case 'image':
|
package/index.js
CHANGED
|
@@ -84,7 +84,15 @@ export const mount$u = function() {
|
|
|
84
84
|
uni.$u = $u
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
function toCamelCase(str) {
|
|
88
|
+
return str.replace(/-([a-z])/g, function(match, group1) {
|
|
89
|
+
return group1.toUpperCase();
|
|
90
|
+
}).replace(/^[a-z]/, function(match) {
|
|
91
|
+
return match.toUpperCase();
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// #ifdef APP || H5
|
|
88
96
|
const importFn = import.meta.glob('./components/u-*/u-*.vue', { eager: true })
|
|
89
97
|
let components = [];
|
|
90
98
|
|
|
@@ -102,18 +110,13 @@ for (const key in importFn) {
|
|
|
102
110
|
}
|
|
103
111
|
// #endif
|
|
104
112
|
|
|
105
|
-
function toCamelCase(str) {
|
|
106
|
-
return str.replace(/-([a-z])/g, function(match, group1) {
|
|
107
|
-
return group1.toUpperCase();
|
|
108
|
-
}).replace(/^[a-z]/, function(match) {
|
|
109
|
-
return match.toUpperCase();
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
|
|
113
113
|
const install = (Vue, upuiParams = '') => {
|
|
114
|
-
// #ifdef H5
|
|
114
|
+
// #ifdef APP || H5
|
|
115
115
|
components.forEach(function(component) {
|
|
116
116
|
const name = component.name.replace(/u-([a-zA-Z0-9-_]+)/g, 'up-$1');
|
|
117
|
+
if (name != component.name) {
|
|
118
|
+
Vue.component(component.name, component);
|
|
119
|
+
}
|
|
117
120
|
Vue.component(name, component);
|
|
118
121
|
});
|
|
119
122
|
// #endif
|
package/package.json
CHANGED