uview-plus 3.4.20 → 3.4.23

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 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
 
@@ -5,7 +5,11 @@ export const props = defineMixin({
5
5
  // 是否显示input
6
6
  hasInput: {
7
7
  type: Boolean,
8
- default: () => false
8
+ default: false
9
+ },
10
+ inputBorder: {
11
+ type: String,
12
+ default: 'surround'
9
13
  },
10
14
  disabled: {
11
15
  type: Boolean,
@@ -7,7 +7,7 @@
7
7
  <up-input
8
8
  :placeholder="placeholder"
9
9
  :readonly="!!showByClickInput"
10
- border="surround"
10
+ :border="inputBorder"
11
11
  v-model="inputValue"
12
12
  :disabled="disabled"
13
13
  :disabledColor="disabledColor"
@@ -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,
@@ -129,6 +129,10 @@ export const props = defineMixin({
129
129
  autoBlur: {
130
130
  type: Boolean,
131
131
  default: () => false
132
+ },
133
+ iconPosition: {
134
+ type: String,
135
+ default: () => defProps.search.iconPosition
132
136
  }
133
137
  }
134
138
  })
@@ -27,6 +27,7 @@ export default {
27
27
  color: '#606266',
28
28
  placeholderColor: '#909399',
29
29
  searchIcon: 'search',
30
+ iconPosition: 'left',
30
31
  margin: '0',
31
32
  animation: false,
32
33
  value: '',
@@ -1,6 +1,7 @@
1
1
  <template>
2
2
  <view
3
3
  class="u-search"
4
+ :class="[iconPosition === 'right' && 'u-search__reverse']"
4
5
  @tap="clickHandler"
5
6
  :style="[{
6
7
  margin: margin,
@@ -100,6 +101,7 @@
100
101
  * @property {String} color 输入框字体颜色(默认 '#606266' )
101
102
  * @property {String} placeholderColor placeholder的颜色(默认 '#909399' )
102
103
  * @property {String} searchIcon 输入框左边的图标,可以为uView图标名称或图片路径 (默认 'search' )
104
+ * @property {String} iconPosition 输入框图标位置,left-左边, right-右边 (默认 'left' )
103
105
  * @property {String} margin 组件与其他上下左右元素之间的距离,带单位的字符串形式,如"30px" (默认 '0' )
104
106
  * @property {Boolean} animation 是否开启动画,见上方说明(默认 false )
105
107
  * @property {String} value 输入框初始值
@@ -328,5 +330,13 @@ $u-search-action-margin-left: 5px !default;
328
330
  margin-left: $u-search-action-margin-left;
329
331
  }
330
332
  }
333
+
334
+ &__reverse &__content__icon {
335
+ order: 3;
336
+ }
337
+
338
+ &__reverse &__content__close {
339
+ order: 2;
340
+ }
331
341
  }
332
342
  </style>
@@ -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
@@ -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
  },
@@ -14,7 +14,7 @@ export default {
14
14
  cancelText: '取消',
15
15
  confirmText: '确认',
16
16
  cancelColor: '#909193',
17
- confirmColor: '#3c9cff',
17
+ confirmColor: '',
18
18
  title: ''
19
19
  }
20
20
 
@@ -106,6 +106,7 @@
106
106
  color: $u-main-color;
107
107
  padding: 0 60rpx;
108
108
  font-size: 16px;
109
+ font-weight: bold;
109
110
  flex: 1;
110
111
  text-align: center;
111
112
  }
@@ -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' : 'folder'"
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>
@@ -197,6 +200,7 @@
197
200
  * @tutorial https://uview-plus.jiangruyi.com/components/upload.html
198
201
  * @property {String} accept 接受的文件类型, 可选值为all media image file video (默认 'image' )
199
202
  * @property {String | Array} capture 图片或视频拾取模式,当accept为image类型时设置capture可选额外camera可以直接调起摄像头(默认 ['album', 'camera'] )
203
+ * @property {Array} extension 选择文件的后缀名,暂只支持.zip、.png等,不支持application/msword等值
200
204
  * @property {Boolean} compressed 当accept为video时生效,是否压缩视频,默认为true(默认 true )
201
205
  * @property {String} camera 当accept为video时生效,可选值为back或front(默认 'back' )
202
206
  * @property {Number} maxDuration 当accept为video时生效,拍摄视频最长拍摄时间,单位秒(默认 60 )
@@ -327,48 +331,44 @@
327
331
  const {
328
332
  fileList = [], maxCount
329
333
  } = this;
330
- const lists = fileList.map((item) =>
331
- Object.assign(Object.assign({}, item), {
334
+ const lists = fileList.map((item) => {
335
+ const name = item.name || item.url || item.thumb
336
+ return Object.assign(Object.assign({}, item), {
332
337
  // 如果item.url为本地选择的blob文件的话,无法判断其为video还是image,此处优先通过accept做判断处理
333
- isImage: this.accept === 'image' || test.image(item.url || item.thumb),
334
- isVideo: this.accept === 'video' || test.video(item.url || item.thumb),
335
- deletable: typeof(item.deletable) === 'boolean' ? item.deletable : this.deletable,
338
+ isImage: item.name ? test.image(item.name) : (this.accept === 'image' || test.image(name)),
339
+ isVideo: item.name ? test.video(item.name) : (this.accept === 'video' || test.video(name)),
340
+ deletable: typeof item.deletable === 'boolean' ? item.deletable : this.deletable,
336
341
  })
337
- );
342
+ });
338
343
  this.lists = lists
339
344
  this.isInCount = lists.length < maxCount
340
345
  },
341
- chooseFile() {
346
+ chooseFile(params) {
342
347
  const {
343
348
  maxCount,
344
349
  multiple,
345
350
  lists,
346
351
  disabled
347
352
  } = this;
348
- if (disabled) return;
349
- // 如果用户传入的是字符串,需要格式化成数组
350
- let capture;
351
- try {
352
- capture = test.array(this.capture) ? this.capture : this.capture.split(',');
353
- }catch(e) {
354
- capture = [];
355
- }
356
- chooseFile(
357
- Object.assign({
358
- accept: this.accept,
359
- extension: this.extension,
360
- multiple: this.multiple,
361
- capture: capture,
362
- compressed: this.compressed,
363
- maxDuration: this.maxDuration,
364
- sizeType: this.sizeType,
365
- camera: this.camera,
366
- }, {
367
- maxCount: maxCount - lists.length,
368
- })
369
- )
353
+ if (disabled) return Promise.reject();
354
+ const chooseParams = Object.assign({
355
+ accept: this.accept,
356
+ extension: this.extension,
357
+ multiple: this.multiple,
358
+ capture: this.capture,
359
+ compressed: this.compressed,
360
+ maxDuration: this.maxDuration,
361
+ sizeType: this.sizeType,
362
+ camera: this.camera,
363
+ }, {
364
+ maxCount: maxCount - lists.length,
365
+ ...params
366
+ })
367
+ return chooseFile(chooseParams)
370
368
  .then((res) => {
371
- this.onBeforeRead(multiple ? res : res[0]);
369
+ const result = chooseParams.multiple ? res : res[0]
370
+ this.onBeforeRead(result);
371
+ return result
372
372
  })
373
373
  .catch((error) => {
374
374
  this.$emit('error', error);
@@ -587,7 +587,8 @@
587
587
  let item = this.fileList[index];
588
588
  this.fileList.splice(index, 1, {
589
589
  ...item,
590
- status: 'uploading',
590
+ // 注意这里不判断会出现succcessUpload先执行又被覆盖的问题
591
+ status: param.progress == 100 ? 'success' : 'uploading',
591
592
  message: '',
592
593
  progress: param.progress
593
594
  });
@@ -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/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "id": "uview-plus",
3
3
  "name": "uview-plus",
4
4
  "displayName": "零云®uview-plus3.0重磅发布,全面的Vue3鸿蒙移动组件库。",
5
- "version": "3.4.20",
5
+ "version": "3.4.23",
6
6
  "description": "零云®uview-plus已兼容vue3,全面的组件和便捷的工具会让您信手拈来,如鱼得水。",
7
7
  "keywords": [
8
8
  "uview",
@@ -89,6 +89,11 @@ declare interface SearchProps {
89
89
  * @default "search"
90
90
  */
91
91
  searchIcon?: string
92
+ /**
93
+ * 输入框图标位置,left-左边,right-右边
94
+ * @default "left"
95
+ */
96
+ iconPosition?: 'left' | 'right'
92
97
  /**
93
98
  * 组件与其他上下左右元素之间的距离,带单位的字符串形式,如"30rpx"、"30rpx 20rpx"等写法
94
99
  * @default "0"
@@ -1,6 +1,33 @@
1
1
  import { AllowedComponentProps, VNodeProps } from './_common'
2
2
  import { ImageMode } from './image';
3
3
 
4
+ type BaseFileInfo = {
5
+ type: string
6
+ url: string
7
+ name: string
8
+ size: number
9
+ file: File
10
+ [key: string]: any
11
+ }
12
+
13
+ type ImageFileInfo = BaseFileInfo & {
14
+ type: 'image'
15
+ thumb: string
16
+ }
17
+
18
+ type VideoFileInfo = BaseFileInfo & {
19
+ type: 'video'
20
+ thumb: string
21
+ width: number
22
+ height: number
23
+ }
24
+
25
+ type MediaFileInfo = BaseFileInfo & {
26
+ thumb: string
27
+ }
28
+
29
+ type FileInfo = BaseFileInfo | ImageFileInfo | VideoFileInfo | MediaFileInfo
30
+
4
31
  declare interface UploadProps {
5
32
  /**
6
33
  * 接受的文件类型,file只支持H5(只有微信小程序才支持把accept配置为all、media)
@@ -12,6 +39,10 @@ declare interface UploadProps {
12
39
  * @default ["album", "camera"]
13
40
  */
14
41
  capture?: 'album' | 'camera' | ('album' | 'camera')[]
42
+ /**
43
+ * 选择文件的后缀名,暂只支持.zip、.png等,不支持application/msword等值
44
+ */
45
+ extension?: string [];
15
46
  /**
16
47
  * 当accept为video时生效,是否压缩视频,默认为true
17
48
  * @default true
@@ -131,6 +162,11 @@ declare interface UploadProps {
131
162
  onDelete?: (index, file, name) => any
132
163
  }
133
164
 
165
+ type ChooseFileParams = Pick<
166
+ UploadProps,
167
+ 'accept' | 'multiple' | 'capture' | 'compressed' | 'maxDuration' | 'sizeType' | 'camera' | 'maxCount' | 'extension'
168
+ >;
169
+
134
170
  declare interface UploadSlots {
135
171
  /**
136
172
  * 自定义上传样式
@@ -147,6 +183,11 @@ declare interface _UploadRef {
147
183
  * 读取前的处理函数
148
184
  */
149
185
  beforeRead: (file, lists, name) => any
186
+ /**
187
+ * 触发文件选择器
188
+ */
189
+ chooseFile(params: ChooseFileParams & { multiple: true }): Promise<FileInfo[]>;
190
+ chooseFile(params?: ChooseFileParams & { multiple?: false }): Promise<FileInfo>;
150
191
  }
151
192
 
152
193
  declare interface _Upload {