uview-plus 3.3.53 → 3.3.55

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,11 @@
1
+ ## 3.3.55(2024-12-17)
2
+ add: swiper增加双向绑定
3
+
4
+ ## 3.3.54(2024-12-11)
5
+ add: qrcode支持props控制是否开启点击预览
6
+
7
+ add: 新增cate-tab垂直分类组件
8
+
1
9
  ## 3.3.53(2024-12-10)
2
10
  fix: 修复popup居中模式点击内容区域触发关闭
3
11
 
@@ -79,6 +79,7 @@
79
79
  * @property {String | Number} fontSize 字体大小 (默认 14 )
80
80
  * @property {Object} customStyle 定义需要用到的外部样式
81
81
  * @event {Function} click 点击组件时触发
82
+ * @event {Function} close 点击关闭按钮时触发
82
83
  * @example <u-alert :title="title" type = "warning" :closable="closable" :description = "description"></u-alert>
83
84
  */
84
85
  export default {
@@ -116,7 +117,7 @@
116
117
  }
117
118
  }
118
119
  },
119
- emits: ["click"],
120
+ emits: ["click","close"],
120
121
  methods: {
121
122
  addUnit,
122
123
  addStyle,
@@ -126,7 +127,8 @@
126
127
  },
127
128
  // 点击关闭按钮
128
129
  closeHandler() {
129
- this.show = false
130
+ this.show = false
131
+ this.$emit('close')
130
132
  }
131
133
  }
132
134
  }
@@ -0,0 +1,313 @@
1
+ <template>
2
+ <view class="u-cate-tab">
3
+ <view class="u-cate-tab__wrap">
4
+ <scroll-view class="u-cate-tab__view u-cate-tab__menu-scroll-view"
5
+ scroll-y scroll-with-animation :scroll-top="scrollTop"
6
+ :scroll-into-view="itemId">
7
+ <view v-for="(item, index) in tabList" :key="index" class="u-cate-tab__item"
8
+ :class="[current == index ? 'u-cate-tab__item-active' : '']"
9
+ @tap.stop="swichMenu(index)">
10
+ <slot name="tabItem" :item="item">
11
+ <text class="u-line-1">{{item[tabKeyName]}}</text>
12
+ </slot>
13
+ </view>
14
+ </scroll-view>
15
+ <scroll-view :scroll-top="scrollRightTop" scroll-y scroll-with-animation class="u-cate-tab__right-box" @scroll="rightScroll">
16
+ <view class="u-cate-tab__page-view">
17
+ <view class="u-cate-tab__page-item" :id="'item' + index" v-for="(item , index) in tabList" :key="index">
18
+ <slot name="itemList" :item="item">
19
+ <view class="item-title">
20
+ <text>{{item[tabKeyName]}}</text>
21
+ </view>
22
+ <view class="item-container">
23
+ <template v-for="(item1, index1) in item.children" :key="index1">
24
+ <slot name="pageItem" :pageItem="item1">
25
+ <view class="thumb-box" >
26
+ <image class="item-menu-image" :src="item1.icon" mode=""></image>
27
+ <view class="item-menu-name">{{item1[itemKeyName]}}</view>
28
+ </view>
29
+ </slot>
30
+ </template>
31
+ </view>
32
+ </slot>
33
+ </view>
34
+ </view>
35
+ </scroll-view>
36
+ </view>
37
+ </view>
38
+ </template>
39
+ <script>
40
+ export default {
41
+ props: {
42
+ tabList: {
43
+ type: Array,
44
+ default: () => {
45
+ return []
46
+ }
47
+ },
48
+ tabKeyName: {
49
+ type: String,
50
+ default: 'name'
51
+ },
52
+ itemKeyName: {
53
+ type: String,
54
+ default: 'name'
55
+ }
56
+ },
57
+ watch: {
58
+ tabList() {
59
+ this.getMenuItemTop()
60
+ }
61
+ },
62
+ data() {
63
+ return {
64
+ scrollTop: 0, //tab标题的滚动条位置
65
+ oldScrollTop: 0,
66
+ current: 0, // 预设当前项的值
67
+ menuHeight: 0, // 左边菜单的高度
68
+ menuItemHeight: 0, // 左边菜单item的高度
69
+ itemId: '', // 栏目右边scroll-view用于滚动的id
70
+ menuItemPos: [],
71
+ rects: [],
72
+ arr: [],
73
+ scrollRightTop: 0, // 右边栏目scroll-view的滚动条高度
74
+ timer: null, // 定时器
75
+ }
76
+ },
77
+ onMounted() {
78
+ this.getMenuItemTop()
79
+ },
80
+ methods: {
81
+ // 点击左边的栏目切换
82
+ async swichMenu(index) {
83
+ if(this.arr.length == 0) {
84
+ await this.getMenuItemTop();
85
+ }
86
+ if (index == this.current) return;
87
+ this.scrollRightTop = this.oldScrollTop;
88
+ this.$nextTick(function(){
89
+ this.scrollRightTop = this.arr[index];
90
+ this.current = index;
91
+ this.leftMenuStatus(index);
92
+ })
93
+ },
94
+ // 获取一个目标元素的高度
95
+ getElRect(elClass, dataVal) {
96
+ new Promise((resolve, reject) => {
97
+ const query = uni.createSelectorQuery().in(this);
98
+ query.select('.' + elClass).fields({
99
+ size: true
100
+ }, res => {
101
+ // 如果节点尚未生成,res值为null,循环调用执行
102
+ if (!res) {
103
+ setTimeout(() => {
104
+ this.getElRect(elClass);
105
+ }, 10);
106
+ return;
107
+ }
108
+ this[dataVal] = res.height;
109
+ resolve();
110
+ }).exec();
111
+ })
112
+ },
113
+ // 观测元素相交状态
114
+ async observer() {
115
+ this.tabList.map((val, index) => {
116
+ let observer = uni.createIntersectionObserver(this);
117
+ // 检测右边scroll-view的id为itemxx的元素与u-cate-tab__right-box的相交状态
118
+ // 如果跟.u-cate-tab__right-box底部相交,就动态设置左边栏目的活动状态
119
+ observer.relativeTo('.u-cate-tab__right-box', {
120
+ top: 0
121
+ }).observe('#item' + index, res => {
122
+ if (res.intersectionRatio > 0) {
123
+ let id = res.id.substring(4);
124
+ this.leftMenuStatus(id);
125
+ }
126
+ })
127
+ })
128
+ },
129
+ // 设置左边菜单的滚动状态
130
+ async leftMenuStatus(index) {
131
+ this.current = index;
132
+ // 如果为0,意味着尚未初始化
133
+ if (this.menuHeight == 0 || this.menuItemHeight == 0) {
134
+ await this.getElRect('u-cate-tab__menu-scroll-view', 'menuHeight');
135
+ await this.getElRect('u-cate-tab__item', 'menuItemHeight');
136
+ }
137
+ // 将菜单活动item垂直居中
138
+ this.scrollTop = index * this.menuItemHeight + this.menuItemHeight / 2 - this.menuHeight / 2;
139
+ },
140
+ // 获取右边菜单每个item到顶部的距离
141
+ getMenuItemTop() {
142
+ new Promise(resolve => {
143
+ let selectorQuery = uni.createSelectorQuery();
144
+ selectorQuery.selectAll('.u-cate-tab__page-item').boundingClientRect((rects) => {
145
+ // 如果节点尚未生成,rects值为[](因为用selectAll,所以返回的是数组),循环调用执行
146
+ if(!rects.length) {
147
+ setTimeout(() => {
148
+ this.getMenuItemTop();
149
+ }, 10);
150
+ return ;
151
+ }
152
+ this.rects = rects;
153
+ rects.forEach((rect) => {
154
+ // 这里减去rects[0].top,是因为第一项顶部可能不是贴到导航栏(比如有个搜索框的情况)
155
+ this.arr.push(rect.top - rects[0].top);
156
+ resolve();
157
+ })
158
+ }).exec()
159
+ })
160
+ },
161
+ // 右边菜单滚动
162
+ async rightScroll(e) {
163
+ this.oldScrollTop = e.detail.scrollTop;
164
+ // console.log(e.detail.scrollTop)
165
+ // console.log(JSON.stringify(this.arr))
166
+ if(this.arr.length == 0) {
167
+ await this.getMenuItemTop();
168
+ }
169
+ if(this.timer) return ;
170
+ if(!this.menuHeight) {
171
+ await this.getElRect('u-cate-tab__menu-scroll-view', 'menuHeight');
172
+ }
173
+ setTimeout(() => { // 节流
174
+ this.timer = null;
175
+ // scrollHeight为右边菜单垂直中点位置
176
+ let scrollHeight = e.detail.scrollTop + 1;
177
+ // console.log(e.detail.scrollTop)
178
+ for (let i = 0; i < this.arr.length; i++) {
179
+ let height1 = this.arr[i];
180
+ let height2 = this.arr[i + 1];
181
+ // console.log('i', i)
182
+ // console.log('height1', height1)
183
+ // console.log('height2', height2)
184
+ // 如果不存在height2,意味着数据循环已经到了最后一个,设置左边菜单为最后一项即可
185
+ if (!height2 || scrollHeight >= height1 && scrollHeight <= height2) {
186
+ // console.log('scrollHeight', scrollHeight)
187
+ // console.log('height1', height1)
188
+ // console.log('height2', height2)
189
+ this.leftMenuStatus(i);
190
+ return ;
191
+ }
192
+ }
193
+ }, 10)
194
+ }
195
+ }
196
+ }
197
+ </script>
198
+
199
+ <style lang="scss" scoped>
200
+ .u-cate-tab {
201
+ display: flex;
202
+ flex-direction: column;
203
+ }
204
+
205
+ .u-cate-tab__wrap {
206
+ flex: 1;
207
+ display: flex;
208
+ overflow: hidden;
209
+ }
210
+
211
+ .u-search-inner {
212
+ background-color: rgb(234, 234, 234);
213
+ border-radius: 100rpx;
214
+ display: flex;
215
+ align-items: center;
216
+ padding: 10rpx 16rpx;
217
+ }
218
+
219
+ .u-search-text {
220
+ font-size: 26rpx;
221
+ color: $u-tips-color;
222
+ margin-left: 10rpx;
223
+ }
224
+
225
+ .u-cate-tab__view {
226
+ width: 200rpx;
227
+ height: 100%;
228
+ }
229
+
230
+ .u-cate-tab__item {
231
+ height: 110rpx;
232
+ background: #f6f6f6;
233
+ box-sizing: border-box;
234
+ display: flex;
235
+ align-items: center;
236
+ justify-content: center;
237
+ font-size: 26rpx;
238
+ color: #444;
239
+ font-weight: 400;
240
+ line-height: 1;
241
+ }
242
+
243
+ .u-cate-tab__item-active {
244
+ position: relative;
245
+ color: #000;
246
+ font-size: 30rpx;
247
+ font-weight: 600;
248
+ background: #fff;
249
+ }
250
+
251
+ .u-cate-tab__item-active::before {
252
+ content: "";
253
+ position: absolute;
254
+ border-left: 4px solid $u-primary;
255
+ height: 32rpx;
256
+ left: 0;
257
+ top: 39rpx;
258
+ }
259
+
260
+ .u-cate-tab__view {
261
+ height: 100%;
262
+ }
263
+
264
+ .u-cate-tab__right-box {
265
+ background-color: rgb(250, 250, 250);
266
+ }
267
+
268
+ .u-cate-tab__page-view {
269
+ padding: 16rpx;
270
+ }
271
+
272
+ .u-cate-tab__page-item {
273
+ margin-bottom: 30rpx;
274
+ background-color: #fff;
275
+ padding: 16rpx;
276
+ border-radius: 8rpx;
277
+ }
278
+
279
+ .u-cate-tab__page-item:last-child {
280
+ min-height: 100vh;
281
+ }
282
+
283
+ .item-title {
284
+ font-size: 26rpx;
285
+ color: $u-main-color;
286
+ font-weight: bold;
287
+ }
288
+
289
+ .item-menu-name {
290
+ font-weight: normal;
291
+ font-size: 24rpx;
292
+ color: $u-main-color;
293
+ }
294
+
295
+ .item-container {
296
+ display: flex;
297
+ flex-wrap: wrap;
298
+ }
299
+
300
+ .thumb-box {
301
+ width: 33.333333%;
302
+ display: flex;
303
+ align-items: center;
304
+ justify-content: center;
305
+ flex-direction: column;
306
+ margin-top: 20rpx;
307
+ }
308
+
309
+ .item-menu-image {
310
+ width: 120rpx;
311
+ height: 120rpx;
312
+ }
313
+ </style>
@@ -99,6 +99,10 @@ export default {
99
99
  type: String,
100
100
  default: '生成中'
101
101
  },
102
+ allowPreview: {
103
+ type: Boolean,
104
+ default: false
105
+ },
102
106
  },
103
107
  emits: ['result', 'longpress'],
104
108
  data() {
@@ -189,26 +193,31 @@ export default {
189
193
  });
190
194
  }
191
195
  },
192
- preview() {
196
+ preview(e) {
193
197
  // 预览图片
194
198
  // console.log(this.result)
195
- uni.previewImage({
196
- urls: [this.result],
197
- longPressActions: {
198
- itemList: ['保存二维码图片'],
199
- success: function(data) {
200
- // console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片');
201
- switch (data.tapIndex) {
202
- case 0:
203
- that._saveCode();
204
- break;
199
+ if (this.allowPreview) {
200
+ uni.previewImage({
201
+ urls: [this.result],
202
+ longPressActions: {
203
+ itemList: ['保存二维码图片'],
204
+ success: function(data) {
205
+ // console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片');
206
+ switch (data.tapIndex) {
207
+ case 0:
208
+ that._saveCode();
209
+ break;
210
+ }
211
+ },
212
+ fail: function(err) {
213
+ console.log(err.errMsg);
205
214
  }
206
- },
207
- fail: function(err) {
208
- console.log(err.errMsg);
209
215
  }
210
- }
211
- });
216
+ });
217
+ }
218
+ this.$emit('preview', {
219
+ url: this.result
220
+ }, e)
212
221
  },
213
222
  longpress() {
214
223
  this.$emit('longpress', this.result)
@@ -2,6 +2,7 @@
2
2
  <view
3
3
  :style="[style]"
4
4
  class="u-status-bar"
5
+ :class="[isH5 && 'u-safe-area-inset-top']"
5
6
  >
6
7
  <slot />
7
8
  </view>
@@ -25,6 +26,9 @@
25
26
  mixins: [mpMixin, mixin, props],
26
27
  data() {
27
28
  return {
29
+ // #ifdef H5
30
+ isH5: true
31
+ // #endif
28
32
  }
29
33
  },
30
34
  computed: {
@@ -143,7 +143,7 @@
143
143
  this.currentIndex = val; // 和上游数据关联上
144
144
  }
145
145
  },
146
- emits: ["click", "change"],
146
+ emits: ["click", "change", "update:current"],
147
147
  computed: {
148
148
  itemStyle() {
149
149
  return index => {
@@ -189,6 +189,7 @@
189
189
  } = e.detail
190
190
  this.pauseVideo(this.currentIndex)
191
191
  this.currentIndex = current
192
+ this.$emit('update:current', this.currentIndex)
192
193
  this.$emit('change', e.detail)
193
194
  },
194
195
  // 切换轮播时,暂停视频播放
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.3.53",
5
+ "version": "3.3.55",
6
6
  "description": "零云®uview-plus已兼容vue3,全面的组件和便捷的工具会让您信手拈来,如鱼得水",
7
7
  "keywords": [
8
8
  "uview",