uview-plus 3.3.52 → 3.3.54

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.54(2024-12-11)
2
+ add: qrcode支持props控制是否开启点击预览
3
+
4
+ add: 新增cate-tab垂直分类组件
5
+
6
+ ## 3.3.53(2024-12-10)
7
+ fix: 修复popup居中模式点击内容区域触发关闭
8
+
1
9
  ## 3.3.52(2024-12-09)
2
10
  add: notice-bar支持justifyContent属性
3
11
 
@@ -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>
@@ -11,7 +11,7 @@
11
11
  :class="iconClasses"
12
12
  :style="[iconWrapStyle]"
13
13
  >
14
- <slot name="icon">
14
+ <slot name="icon" :elIconSize="elIconSize" :elIconColor="elIconColor">
15
15
  <u-icon
16
16
  class="u-checkbox__icon-wrap__icon"
17
17
  name="checkbox-mark"
@@ -17,9 +17,11 @@
17
17
  @afterEnter="afterEnter"
18
18
  @click="clickHandler"
19
19
  >
20
+ <!-- @click.stop不能去除,去除会导致居中模式下点击内容区域触发关闭弹窗 -->
20
21
  <view
21
22
  class="u-popup__content"
22
23
  :style="[contentStyle]"
24
+ @click.stop="noop"
23
25
  @touchmove.stop.prevent="noop"
24
26
  >
25
27
  <u-status-bar v-if="safeAreaInsetTop"></u-status-bar>
@@ -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)
@@ -11,7 +11,7 @@
11
11
  :class="iconClasses"
12
12
  :style="[iconWrapStyle]"
13
13
  >
14
- <slot name="icon">
14
+ <slot name="icon" :elIconSize="elIconSize" :elIconColor="elIconColor">
15
15
  <u-icon
16
16
  class="u-radio__icon-wrap__icon"
17
17
  name="checkbox-mark"
@@ -103,7 +103,7 @@
103
103
 
104
104
  // 自动伸缩
105
105
  .u-flex-fill,
106
- .u-flex-fillp {
106
+ .up-flex-fill {
107
107
  flex: 1 1 auto;
108
108
  }
109
109
 
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.52",
5
+ "version": "3.3.54",
6
6
  "description": "零云®uview-plus已兼容vue3,全面的组件和便捷的工具会让您信手拈来,如鱼得水",
7
7
  "keywords": [
8
8
  "uview",