uview-plus 3.4.24 → 3.4.26

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,21 @@
1
+ ## 3.4.26(2025-05-06)
2
+ fix: 修复test工具引入
3
+
4
+ feat: card组件支持全局设置props默认值
5
+
6
+ fix: 修复image在加载错误情况下高度和宽度不正确问题
7
+
8
+ fix: 修复picker-data快捷组件默认picker选中
9
+
10
+ fix: 修复日历month子组件缺失emits定义
11
+
12
+ ## 3.4.25(2025-04-27)
13
+ fix: up-form编译在微信小程序里样式缺失 #640
14
+
15
+ fix: number-box输入为空时自动设为最小值
16
+
17
+ feat: picker与datetimepicke组件hasInput模式支持inputProps属性
18
+
1
19
  ## 3.4.24(2025-04-25)
2
20
  fix: 修复upload上传逻辑(感谢@semdy)
3
21
 
@@ -292,6 +292,7 @@
292
292
  mounted() {
293
293
  this.init()
294
294
  },
295
+ emits: ['monthSelected', 'updateMonthTop'],
295
296
  methods: {
296
297
  init() {
297
298
  // 初始化默认选中
@@ -0,0 +1,40 @@
1
+ /*
2
+ * @Author : jry
3
+ * @Description :
4
+ * @version : 3.0
5
+ * @Date : 2025-04-26 16:37:21
6
+ * @LastAuthor : jry
7
+ * @lastTime : 2025-04-26 16:37:21
8
+ * @FilePath : /uview-plus/libs/config/props/card.js
9
+ */
10
+ export default {
11
+ // cell组件的props
12
+ cell: {
13
+ full: false,
14
+ title: '',
15
+ titleColor: '#303133',
16
+ titleSize: '15px',
17
+ subTitle: '',
18
+ subTitleColor: '#909399',
19
+ subTitleSize: '13px',
20
+ border: true,
21
+ index: '',
22
+ margin: '15px',
23
+ borderRadius: '8px',
24
+ headStyle: {},
25
+ bodyStyle: {},
26
+ footStyle: {},
27
+ headBorderBottom: true,
28
+ footBorderTop: true,
29
+ thumb: '',
30
+ thumbWidth: '30px',
31
+ thumbCircle: false,
32
+ padding: '15px',
33
+ paddingHead: '',
34
+ paddingBody: '',
35
+ paddingFoot: '',
36
+ showHead: true,
37
+ showFoot: true,
38
+ boxShadow: 'none'
39
+ }
40
+ }
@@ -6,135 +6,129 @@ export const propsCard = defineMixin({
6
6
  // 与屏幕两侧是否留空隙
7
7
  full: {
8
8
  type: Boolean,
9
- default: false
9
+ default: () => defProps.card.full
10
10
  },
11
11
  // 标题
12
12
  title: {
13
13
  type: String,
14
- default: ''
14
+ default: () => defProps.card.title
15
15
  },
16
16
  // 标题颜色
17
17
  titleColor: {
18
18
  type: String,
19
- default: '#303133'
19
+ default: () => defProps.card.titleColor
20
20
  },
21
21
  // 标题字体大小
22
22
  titleSize: {
23
23
  type: [Number, String],
24
- default: '15px'
24
+ default: () => defProps.card.titleSize
25
25
  },
26
26
  // 副标题
27
27
  subTitle: {
28
28
  type: String,
29
- default: ''
29
+ default: () => defProps.card.subTitle
30
30
  },
31
31
  // 副标题颜色
32
32
  subTitleColor: {
33
33
  type: String,
34
- default: '#909399'
34
+ default: () => defProps.card.subTitleColor
35
35
  },
36
36
  // 副标题字体大小
37
37
  subTitleSize: {
38
38
  type: [Number, String],
39
- default: '13'
39
+ default: () => defProps.card.subTitleSize
40
40
  },
41
41
  // 是否显示外部边框,只对full=false时有效(卡片与边框有空隙时)
42
42
  border: {
43
43
  type: Boolean,
44
- default: true
44
+ default: () => defProps.card.border
45
45
  },
46
46
  // 用于标识点击了第几个
47
47
  index: {
48
48
  type: [Number, String, Object],
49
- default: ''
49
+ default: () => defProps.card.index
50
50
  },
51
51
  // 用于隔开上下左右的边距,带单位的写法,如:"30px 30px","20px 20px 30px 30px"
52
52
  margin: {
53
53
  type: String,
54
- default: '15px'
54
+ default: () => defProps.card.margin
55
55
  },
56
56
  // card卡片的圆角
57
57
  borderRadius: {
58
58
  type: [Number, String],
59
- default: '8px'
59
+ default: () => defProps.card.borderRadius
60
60
  },
61
61
  // 头部自定义样式,对象形式
62
62
  headStyle: {
63
63
  type: Object,
64
- default() {
65
- return {};
66
- }
64
+ default: () => defProps.card.headStyle
67
65
  },
68
66
  // 主体自定义样式,对象形式
69
67
  bodyStyle: {
70
68
  type: Object,
71
- default() {
72
- return {};
73
- }
69
+ default: () => defProps.card.bodyStyle
74
70
  },
75
71
  // 底部自定义样式,对象形式
76
72
  footStyle: {
77
73
  type: Object,
78
- default() {
79
- return {};
80
- }
74
+ default: () => defProps.card.footStyle
81
75
  },
82
76
  // 头部是否下边框
83
77
  headBorderBottom: {
84
78
  type: Boolean,
85
- default: true
79
+ default: () => defProps.card.headBorderBottom
86
80
  },
87
81
  // 底部是否有上边框
88
82
  footBorderTop: {
89
83
  type: Boolean,
90
- default: true
84
+ default: () => defProps.card.footBorderTop
91
85
  },
92
86
  // 标题左边的缩略图
93
87
  thumb: {
94
88
  type: String,
95
- default: ''
89
+ default: () => defProps.card.thumb
96
90
  },
97
91
  // 缩略图宽高
98
92
  thumbWidth: {
99
93
  type: [String, Number],
100
- default: '30px'
94
+ default: () => defProps.card.thumbWidth
101
95
  },
102
96
  // 缩略图是否为圆形
103
97
  thumbCircle: {
104
98
  type: Boolean,
105
- default: false
99
+ default: () => defProps.card.thumbCircle
106
100
  },
107
101
  // 给head,body,foot的内边距
108
102
  padding: {
109
103
  type: [String, Number],
110
- default: '15px'
104
+ default: () => defProps.card.padding
111
105
  },
112
106
  paddingHead: {
113
107
  type: [String, Number],
114
- default: ''
108
+ default: () => defProps.card.paddingHead
115
109
  },
116
110
  paddingBody: {
117
111
  type: [String, Number],
118
- default: ''
112
+ default: () => defProps.card.paddingBody
119
113
  },
120
114
  paddingFoot: {
121
115
  type: [String, Number],
122
- default: ''
116
+ default: () => defProps.card.paddingFoot
123
117
  },
124
118
  // 是否显示头部
125
119
  showHead: {
126
120
  type: Boolean,
127
- default: true
121
+ default: () => defProps.card.showHead
128
122
  },
129
123
  // 是否显示尾部
130
124
  showFoot: {
131
125
  type: Boolean,
132
- default: true
126
+ default: () => defProps.card.showFoot
133
127
  },
134
128
  // 卡片外围阴影,字符串形式
135
129
  boxShadow: {
136
130
  type: String,
137
- default: 'none'
131
+ default: () => defProps.card.boxShadow
138
132
  }
139
133
  }
140
134
  })
@@ -32,6 +32,11 @@ export default {
32
32
  confirmColor: '#3c9cff',
33
33
  visibleItemCount: 5,
34
34
  closeOnClickOverlay: false,
35
- defaultIndex: []
35
+ defaultIndex: [],
36
+ inputBorder: 'surround',
37
+ disabled: false,
38
+ disabledColor: '',
39
+ placeholder: '请选择',
40
+ inputProps: {},
36
41
  }
37
42
  }
@@ -7,13 +7,19 @@ export const props = defineMixin({
7
7
  type: Boolean,
8
8
  default: false
9
9
  },
10
+ inputProps: {
11
+ type: Object,
12
+ default: () => {
13
+ return {}
14
+ }
15
+ },
10
16
  inputBorder: {
11
17
  type: String,
12
- default: 'surround'
18
+ default: () => defProps.input.inputBorder
13
19
  },
14
20
  disabled: {
15
21
  type: Boolean,
16
- default: () => false
22
+ default: () => defProps.input.disabled
17
23
  },
18
24
  disabledColor:{
19
25
  type: String,
@@ -21,7 +27,7 @@ export const props = defineMixin({
21
27
  },
22
28
  placeholder: {
23
29
  type: String,
24
- default: () => '请选择'
30
+ default: () => defProps.input.placeholder
25
31
  },
26
32
  format: {
27
33
  type: String,
@@ -5,12 +5,9 @@
5
5
  >
6
6
  <slot name="trigger" :value="inputValue">
7
7
  <up-input
8
- :placeholder="placeholder"
9
8
  :readonly="!!showByClickInput"
10
- :border="inputBorder"
11
9
  v-model="inputValue"
12
- :disabled="disabled"
13
- :disabledColor="disabledColor"
10
+ v-bind="inputPropsInner"
14
11
  ></up-input>
15
12
  <div class="input-cover">
16
13
  </div>
@@ -135,6 +132,16 @@
135
132
  // 如果以下这些变量发生了变化,意味着需要重新初始化各列的值
136
133
  propsChange() {
137
134
  return [this.mode, this.maxDate, this.minDate, this.minHour, this.maxHour, this.minMinute, this.maxMinute, this.filter, ]
135
+ },
136
+ // input的props
137
+ inputPropsInner() {
138
+ return {
139
+ border: this.inputBorder,
140
+ placeholder: this.placeholder,
141
+ disabled: this.disabled,
142
+ disabledColor: this.disabledColor,
143
+ ...this.inputProps
144
+ }
138
145
  }
139
146
  },
140
147
  mounted() {
@@ -240,10 +240,8 @@
240
240
 
241
241
  &__slot {
242
242
  flex: 1;
243
- /* #ifndef MP */
244
243
  @include flex;
245
244
  align-items: center;
246
- /* #endif */
247
245
  }
248
246
 
249
247
  &__icon {
@@ -132,12 +132,12 @@
132
132
  // #endif
133
133
  // #ifndef APP-NVUE
134
134
  if (this.loading || this.isError || this.width == '100%' || this.mode != 'heightFix') {
135
- style.width = this.width;
135
+ style.width = addUnit(this.width);
136
136
  } else {
137
137
  style.width = 'fit-content';
138
138
  }
139
139
  if (this.loading || this.isError || this.height == '100%' || this.mode != 'widthFix') {
140
- style.height = this.height;
140
+ style.height = addUnit(this.height);
141
141
  } else {
142
142
  style.height = 'fit-content';
143
143
  }
@@ -153,12 +153,12 @@
153
153
  // #endif
154
154
  // #ifndef APP-NVUE
155
155
  if (this.loading || this.isError || this.width == '100%' || this.mode != 'heightFix') {
156
- style.width = this.width;
156
+ style.width = addUnit(this.width);
157
157
  } else {
158
158
  style.width = 'fit-content';
159
159
  }
160
160
  if (this.loading || this.isError || this.height == '100%' || this.mode != 'widthFix') {
161
- style.height = this.height;
161
+ style.height = addUnit(this.height);
162
162
  } else {
163
163
  style.height = 'fit-content';
164
164
  }
@@ -311,13 +311,17 @@
311
311
  value = ''
312
312
  } = e.detail || {}
313
313
  // 为空返回
314
- if (value === '') return
314
+ if (value === '') {
315
+ // 为空自动设为最小值
316
+ this.emitChange(this.min)
317
+ return
318
+ }
315
319
  let formatted = this.filter(value)
316
320
  // https://github.com/ijry/uview-plus/issues/613
317
321
  this.emitChange(value);
318
322
  // 最大允许的小数长度
319
323
  if (this.decimalLength !== null && formatted.indexOf('.') !== -1) {
320
- const pair = formatted.split('.');
324
+ const pair = formatted.split('.')
321
325
  formatted = `${pair[0]}.${pair[1].slice(0, this.decimalLength)}`
322
326
  }
323
327
  formatted = this.format(formatted)
@@ -20,12 +20,16 @@ export default {
20
20
  cancelText: '取消',
21
21
  confirmText: '确定',
22
22
  cancelColor: '#909193',
23
- confirmColor: '#3c9cff',
23
+ confirmColor: '',
24
24
  visibleItemCount: 5,
25
25
  keyName: 'text',
26
26
  closeOnClickOverlay: false,
27
27
  defaultIndex: [],
28
28
  immediateChange: true,
29
29
  zIndex: 10076,
30
+ disabled: false,
31
+ disabledColor: '',
32
+ placeholder: '请选择',
33
+ inputProps: {},
30
34
  }
31
35
  }
@@ -6,22 +6,27 @@ export const props = defineMixin({
6
6
  type: Array,
7
7
  default: () => []
8
8
  },
9
- //是否禁用
10
- disabled: {
9
+ hasInput: {
11
10
  type: Boolean,
12
11
  default: false
12
+ },
13
+ inputProps: {
14
+ type: Object,
15
+ default: () => {
16
+ return {}
17
+ }
18
+ },
19
+ disabled: {
20
+ type: Boolean,
21
+ default: () => defProps.picker.disabled
13
22
  },
14
23
  disabledColor:{
15
24
  type: String,
16
- default: () => defProps.input.disabledColor
25
+ default: () => defProps.picker.disabledColor
17
26
  },
18
- hasInput: {
19
- type: Boolean,
20
- default: false
21
- },
22
27
  placeholder: {
23
28
  type: String,
24
- default: () => '请选择'
29
+ default: () => defProps.picker.placeholder
25
30
  },
26
31
  // 是否展示picker弹窗
27
32
  show: {
@@ -1,10 +1,17 @@
1
1
  <template>
2
2
  <view class="u-picker-warrper">
3
- <view v-if="hasInput" class="u-picker-input cursor-pointer" @click="onShowByClickInput">
4
- <slot>
5
- <up-input :disabled="disabled" :disabledColor="disabledColor" :placeholder="placeholder" :readonly="true" border="surround" v-model="inputLabel"></up-input>
6
- <div class="input-cover"></div>
7
- </slot>
3
+ <view v-if="hasInput" class="u-picker-input cursor-pointer" @click="onShowByClickInput">
4
+ <slot :value="inputLabel">
5
+ </slot>
6
+ <slot name="trigger" :value="inputLabel">
7
+ </slot>
8
+ <up-input
9
+ v-if="!$slots['default'] && !$slots['$default'] && !$slots['trigger']"
10
+ :readonly="true"
11
+ v-model="inputLabel"
12
+ v-bind="inputPropsInner">
13
+ </up-input>
14
+ <div class="input-cover"></div>
8
15
  </view>
9
16
  <u-popup
10
17
  :show="show || (hasInput && showByClickInput)"
@@ -122,11 +129,11 @@ export default {
122
129
  immediate: true,
123
130
  deep:true,
124
131
  handler(n,o) {
125
- // 修复uniapp调用子组件直接:defaultIndex="[0]"这样写
126
- // v-model的值变化时候导致defaultIndexwatch也会执行的问题
127
- //单纯vue不会出现
128
- if (!o || n.join("/") != o.join("/")) {
129
- this.setIndexs(n, true)
132
+ // 修复uniapp调用子组件直接:defaultIndex="[0]"这样写
133
+ // v-model的值变化时候导致defaultIndexwatch也会执行的问题
134
+ //单纯vue不会出现
135
+ if (!o || n.join("/") != o.join("/")) {
136
+ this.setIndexs(n, true)
130
137
  }
131
138
  }
132
139
  },
@@ -141,37 +148,47 @@ export default {
141
148
  },
142
149
  emits: ['close', 'cancel', 'confirm', 'change', 'update:modelValue', 'update:show'],
143
150
  computed: {
144
- //已选&&已确认的值显示在input上面的文案
145
- inputLabel() {
146
- let firstItem = this.innerColumns[0] && this.innerColumns[0][0];
147
- // //区分是不是对象数组
148
- if (firstItem && Object.prototype.toString.call(firstItem) === '[object Object]') {
149
- let res = this.innerColumns[0].filter(item => this.modelValue.includes(item['id']))
150
- res = res.map(item => item[this.keyName]);
151
- return res.join("/");
152
-
153
- } else {
154
- //用户确定的值,才显示到输入框
155
- return this.modelValue.join("/");
156
- }
157
- },
158
- //已选,待确认的值
159
- inputValue() {
160
- let items = this.innerColumns.map((item, index) => item[this.innerIndex[index]])
161
- let res = []
162
- //区分是不是对象数组
163
- if (items[0] && Object.prototype.toString.call(items[0]) === '[object Object]') {
164
- //对象数组返回id集合
165
- items.forEach(element => {
166
- res.push(element && element['id'])
167
- });
168
- } else {
169
- //非对象数组返回元素集合
170
- items.forEach((element, index) => {
171
- res.push(element)
172
- });
173
- }
174
- return res
151
+ // input的props
152
+ inputPropsInner() {
153
+ return {
154
+ border: this.inputBorder,
155
+ placeholder: this.placeholder,
156
+ disabled: this.disabled,
157
+ disabledColor: this.disabledColor,
158
+ ...this.inputProps
159
+ }
160
+ },
161
+ //已选&&已确认的值显示在input上面的文案
162
+ inputLabel() {
163
+ let firstItem = this.innerColumns[0] && this.innerColumns[0][0];
164
+ // //区分是不是对象数组
165
+ if (firstItem && Object.prototype.toString.call(firstItem) === '[object Object]') {
166
+ let res = this.innerColumns[0].filter(item => this.modelValue.includes(item['id']))
167
+ res = res.map(item => item[this.keyName]);
168
+ return res.join("/");
169
+
170
+ } else {
171
+ //用户确定的值,才显示到输入框
172
+ return this.modelValue.join("/");
173
+ }
174
+ },
175
+ //已选,待确认的值
176
+ inputValue() {
177
+ let items = this.innerColumns.map((item, index) => item[this.innerIndex[index]])
178
+ let res = []
179
+ //区分是不是对象数组
180
+ if (items[0] && Object.prototype.toString.call(items[0]) === '[object Object]') {
181
+ //对象数组返回id集合
182
+ items.forEach(element => {
183
+ res.push(element && element['id'])
184
+ });
185
+ } else {
186
+ //非对象数组返回元素集合
187
+ items.forEach((element, index) => {
188
+ res.push(element)
189
+ });
190
+ }
191
+ return res
175
192
  }
176
193
  },
177
194
  methods: {
@@ -346,17 +363,17 @@ export default {
346
363
 
347
364
  .u-picker {
348
365
  position: relative;
349
- &-input {
350
- position: relative;
351
- .input-cover {
352
- opacity: 0;
353
- position: absolute;
354
- top: 0;
355
- bottom: 0;
356
- left: 0;
366
+ &-input {
367
+ position: relative;
368
+ .input-cover {
369
+ opacity: 0;
370
+ position: absolute;
371
+ top: 0;
372
+ bottom: 0;
373
+ left: 0;
357
374
  right: 0;
358
- z-index:1;
359
- }
375
+ z-index:1;
376
+ }
360
377
  }
361
378
  &__view {
362
379
 
@@ -17,6 +17,7 @@
17
17
  :show="show"
18
18
  :columns="optionsInner"
19
19
  :keyName="labelKey"
20
+ :defaultIndex="defaultIndex"
20
21
  @confirm="select"
21
22
  @cancel="cancel">
22
23
  </up-picker>
@@ -57,13 +58,15 @@ export default {
57
58
  return {
58
59
  show: false,
59
60
  current: '',
61
+ defaultIndex: [],
60
62
  }
61
63
  },
62
64
  created() {
63
65
  if (this.modelValue) {
64
- this.options.forEach((ele) => {
66
+ this.options.forEach((ele, index) => {
65
67
  if (ele[this.valueKey] == this.modelValue) {
66
68
  this.current = ele[this.labelKey]
69
+ this.defaultIndex = [index]
67
70
  }
68
71
  })
69
72
  }
@@ -74,6 +77,7 @@ export default {
74
77
  this.options.forEach((ele) => {
75
78
  if (ele[this.valueKey] == this.modelValue) {
76
79
  this.current = ele[this.labelKey]
80
+ this.defaultIndex = [index]
77
81
  }
78
82
  })
79
83
  }
@@ -101,8 +105,9 @@ export default {
101
105
  this.show = false;
102
106
  // console.log(value);
103
107
  this.$emit('update:modelValue', value[0][this.valueKey]);
108
+ this.defaultIndex = columnIndex;
104
109
  this.current = value[0][this.labelKey];
105
- },
110
+ }
106
111
  }
107
112
  }
108
113
  </script>
@@ -171,7 +171,7 @@
171
171
  <up-popup
172
172
  mode="center"
173
173
  v-model:show="popupShow">
174
- <video id="myVideo"
174
+ <video id="myVideo" v-if="popupShow"
175
175
  :src="currentItemIndex >= 0 ? lists[currentItemIndex].url : ''"
176
176
  @error="videoErrorCallback" show-center-play-btn
177
177
  object-fit='cover' show-fullscreen-btn='true'
@@ -1,3 +1,4 @@
1
+ import test from '../../libs/function/test'
1
2
  function pickExclude(obj, keys) {
2
3
  // 某些情况下,type可能会为
3
4
  if (!['[object Object]', '[object File]'].includes(Object.prototype.toString.call(obj))) {
@@ -21,30 +22,30 @@ function formatImage(res) {
21
22
  // #ifdef H5
22
23
  name: item.name,
23
24
  file: item
24
- // #endif
25
- // #ifndef H5
26
- name: item.path.split('/').pop() + '.png',
25
+ // #endif
26
+ // #ifndef H5
27
+ name: item.path.split('/').pop() + '.png',
27
28
  // #endif
28
29
  }))
29
30
  }
30
31
 
31
- function formatVideo(res) {
32
- // console.log(res)
32
+ function formatVideo(res) {
33
+ // console.log(res)
33
34
  return [
34
35
  {
35
36
  ...pickExclude(res, ['tempFilePath', 'thumbTempFilePath', 'errMsg']),
36
37
  type: 'video',
37
38
  url: res.tempFilePath,
38
39
  thumb: res.thumbTempFilePath,
39
- size: res.size,
40
- width: res.width || 0, // APP 2.1.0+、H5、微信小程序、京东小程序
40
+ size: res.size,
41
+ width: res.width || 0, // APP 2.1.0+、H5、微信小程序、京东小程序
41
42
  height: res.height || 0, // APP 2.1.0+、H5、微信小程序、京东小程序
42
43
  // #ifdef H5
43
44
  name: res.name,
44
45
  file: res
45
- // #endif
46
- // #ifndef H5
47
- name: res.tempFilePath.split('/').pop() + '.mp4',
46
+ // #endif
47
+ // #ifndef H5
48
+ name: res.tempFilePath.split('/').pop() + '.mp4',
48
49
  // #endif
49
50
  }
50
51
  ]
@@ -59,9 +60,9 @@ function formatMedia(res) {
59
60
  size: item.size,
60
61
  // #ifdef H5
61
62
  file: item
62
- // #endif
63
- // #ifndef H5
64
- name: item.tempFilePath.split('/').pop() + (res.type === 'video' ? '.mp4': '.png'),
63
+ // #endif
64
+ // #ifndef H5
65
+ name: item.tempFilePath.split('/').pop() + (res.type === 'video' ? '.mp4': '.png'),
65
66
  // #endif
66
67
  }))
67
68
  }
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.24",
5
+ "version": "3.4.26",
6
6
  "description": "零云®uview-plus已兼容vue3,全面的组件和便捷的工具会让您信手拈来,如鱼得水。",
7
7
  "keywords": [
8
8
  "uview",