uview-plus 3.4.28 → 3.4.30

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,27 @@
1
+ ## 3.4.30(2025-05-16)
2
+ feat: 新增pagination分页器组件
3
+
4
+ feat: popup新增bottom插槽适用类似关闭按钮与内容区域分离的场景
5
+
6
+ ## 3.4.29(2025-05-15)
7
+ fix: 修复table2横向滚动样式
8
+
9
+ fix: 修复table2组件宽度兼容
10
+
11
+ fix: 修复image显示png图片时默认背景色问题
12
+
13
+ feat: cate-tab新增height参数便于设置组件高度
14
+
15
+ feat: 在index.js种导出digit.js便于使用
16
+
17
+ fix: 修复tag组件缺失iconColor属性
18
+
19
+ fix: 优化index-list的setValueForTouch方法逻辑 #708
20
+
21
+ feat: number-box支持change事件返回变动是点击了增加还是减少按钮
22
+
23
+ fix: 修复table2在小程序下部分情形不显示表格
24
+
1
25
  ## 3.4.28(2025-05-12)
2
26
  feat: 新增table表格组件
3
27
 
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <view class="u-cate-tab">
2
+ <view class="u-cate-tab" :style="{ height: addUnit(height) }">
3
3
  <view class="u-cate-tab__wrap">
4
4
  <scroll-view class="u-cate-tab__view u-cate-tab__menu-scroll-view"
5
5
  scroll-y scroll-with-animation :scroll-top="scrollTop"
@@ -41,9 +41,14 @@
41
41
  </view>
42
42
  </template>
43
43
  <script>
44
+ import { addUnit } from '../../libs/function/index';
44
45
  export default {
45
46
  name: 'up-cate-tab',
46
47
  props: {
48
+ height: {
49
+ type: String,
50
+ default: '100%'
51
+ },
47
52
  tabList: {
48
53
  type: Array,
49
54
  default: () => {
@@ -57,7 +62,7 @@
57
62
  itemKeyName: {
58
63
  type: String,
59
64
  default: 'name'
60
- },
65
+ },
61
66
  current: {
62
67
  type: Number,
63
68
  default: 0
@@ -67,7 +72,7 @@
67
72
  tabList() {
68
73
  this.getMenuItemTop()
69
74
  }
70
- },
75
+ },
71
76
  emits: ['update:current'],
72
77
  data() {
73
78
  return {
@@ -84,18 +89,19 @@
84
89
  timer: null, // 定时器
85
90
  }
86
91
  },
87
- onMounted() {
88
- this.innerCurrent = this.current;
92
+ onMounted() {
93
+ this.innerCurrent = this.current;
89
94
  this.leftMenuStatus(this.innerCurrent);
90
95
  this.getMenuItemTop()
91
- },
92
- watch: {
93
- current(nval) {
94
- this.innerCurrent = nval;
95
- this.leftMenuStatus(this.innerCurrent);
96
- }
96
+ },
97
+ watch: {
98
+ current(nval) {
99
+ this.innerCurrent = nval;
100
+ this.leftMenuStatus(this.innerCurrent);
101
+ }
97
102
  },
98
103
  methods: {
104
+ addUnit,
99
105
  // 点击左边的栏目切换
100
106
  async swichMenu(index) {
101
107
  if(this.arr.length == 0) {
@@ -106,7 +112,7 @@
106
112
  this.$nextTick(function(){
107
113
  this.scrollRightTop = this.arr[index];
108
114
  this.innerCurrent = index;
109
- this.leftMenuStatus(index);
115
+ this.leftMenuStatus(index);
110
116
  this.$emit('update:current', index);
111
117
  })
112
118
  },
@@ -140,14 +146,14 @@
140
146
  }).observe('#item' + index, res => {
141
147
  if (res.intersectionRatio > 0) {
142
148
  let id = res.id.substring(4);
143
- this.leftMenuStatus(id);
149
+ this.leftMenuStatus(id);
144
150
  }
145
151
  })
146
152
  })
147
153
  },
148
154
  // 设置左边菜单的滚动状态
149
155
  async leftMenuStatus(index) {
150
- this.innerCurrent = index;
156
+ this.innerCurrent = index;
151
157
  this.$emit('update:current', index);
152
158
  // 如果为0,意味着尚未初始化
153
159
  if (this.menuHeight == 0 || this.menuItemHeight == 0) {
@@ -45,7 +45,10 @@
45
45
  v-if="showError && isError && !loading"
46
46
  class="u-image__error"
47
47
  :style="{
48
- borderRadius: shape == 'circle' ? '50%' : addUnit(radius)
48
+ borderRadius: shape == 'circle' ? '50%' : addUnit(radius),
49
+ backgroundColor: this.bgColor,
50
+ width: addUnit(width),
51
+ height: addUnit(height)
49
52
  }"
50
53
  >
51
54
  <slot name="error">
@@ -220,9 +223,9 @@
220
223
  // 移除图片的背景色
221
224
  removeBgColor() {
222
225
  // 淡入动画过渡完成后,将背景设置为透明色,否则png图片会看到灰色的背景
223
- this.backgroundStyle = {
224
- backgroundColor: this.bgColor || '#ffffff'
225
- };
226
+ // this.backgroundStyle = {
227
+ // backgroundColor: this.bgColor || '#ffffff'
228
+ // };
226
229
  }
227
230
  }
228
231
  };
@@ -419,7 +419,7 @@
419
419
  return child
420
420
  })
421
421
  // console.log('this.children[currentIndex].top', children[currentIndex].top)
422
- if (children[currentIndex]?.top) {
422
+ if (children[currentIndex]?.top || children[currentIndex].top === 0) {
423
423
  this.scrollTop = children[currentIndex].top - getPx(customNavHeight)
424
424
  }
425
425
  // #endif
@@ -331,8 +331,8 @@
331
331
  // #endif
332
332
 
333
333
  },
334
- // 发出change事件
335
- emitChange(value) {
334
+ // 发出change事件,type目前只支持点击时有值,手动输入不支持。
335
+ emitChange(value, type = '') {
336
336
  // 如果开启了异步变更值,则不修改内部的值,需要用户手动在外部通过v-model变更
337
337
  if (!this.asyncChange) {
338
338
  this.$nextTick(() => {
@@ -349,6 +349,7 @@
349
349
  this.$emit('change', {
350
350
  value,
351
351
  name: this.name,
352
+ type: type // 当前变更类型
352
353
  });
353
354
  },
354
355
  onChange() {
@@ -360,7 +361,7 @@
360
361
  }
361
362
  const diff = type === 'minus' ? -this.step : +this.step
362
363
  const value = this.format(this.add(+this.currentValue, diff))
363
- this.emitChange(value)
364
+ this.emitChange(value, type)
364
365
  this.$emit(type)
365
366
  },
366
367
  // 对值扩大后进行四舍五入,再除以扩大因子,避免出现浮点数操作的精度问题
@@ -0,0 +1,283 @@
1
+ <template>
2
+ <view class="u-pagination">
3
+ <!-- 上一页按钮 -->
4
+ <view
5
+ :class="[
6
+ 'u-pagination-btn',
7
+ { disabled: currentPage === 1 }
8
+ ]"
9
+ :style="{ backgroundColor: buttonBgColor, borderColor: buttonBorderColor }"
10
+ @click="prev"
11
+ >
12
+ <template v-if="prevText">
13
+ {{ prevText }}
14
+ </template>
15
+ <up-icon v-else name="arrow-left"></up-icon>
16
+ </view>
17
+
18
+ <!-- 页码列表 -->
19
+ <block v-for="page in displayedPages" :key="page" v-if="layout.includes('pager')">
20
+ <view
21
+ :class="[
22
+ 'u-pagination-item',
23
+ { active: page === currentPage }
24
+ ]"
25
+ @click="goTo(page)"
26
+ >
27
+ {{ page }}
28
+ </view>
29
+ </block>
30
+
31
+ <!-- 总数显示 -->
32
+ <view v-if="total > 0 && layout.includes('total')" class="u-pagination-total">
33
+ {{ currentPage }} / {{ totalPages }}
34
+ </view>
35
+
36
+ <!-- 每页数量选择器 -->
37
+ <!-- <picker
38
+ v-if="layout.includes('sizes')"
39
+ mode="selector"
40
+ :range="pageSizes"
41
+ range-key="label"
42
+ :value="pageSizeIndex"
43
+ @change="handleSizeChange"
44
+ class="u-pagination-sizes"
45
+ >
46
+ <view>{{ pageSizeLabel }}</view>
47
+ </picker> -->
48
+
49
+ <!-- 下一页按钮 -->
50
+ <view
51
+ :class="[
52
+ 'u-pagination-btn',
53
+ { disabled: currentPage === totalPages }
54
+ ]"
55
+ :style="{ backgroundColor: buttonBgColor, borderColor: buttonBorderColor }"
56
+ @click="next"
57
+ >
58
+ <template v-if="nextText">
59
+ 下一页
60
+ </template>
61
+ <up-icon v-else name="arrow-right"></up-icon>
62
+ </view>
63
+
64
+ <!-- 跳转输入框 -->
65
+ <!-- <view v-if="layout.includes('jumper')">
66
+ <text>前往</text>
67
+ <input
68
+ type="number"
69
+ class="u-pagination-jumper"
70
+ :value="currentPageInput"
71
+ @input="onInputPage"
72
+ @confirm="onConfirmPage"
73
+ />
74
+ <text>页</text>
75
+ </view> -->
76
+ </view>
77
+ </template>
78
+
79
+ <script>
80
+ export default {
81
+ name: 'u-pagination',
82
+ props: {
83
+ // 当前页码
84
+ currentPage: {
85
+ type: Number,
86
+ default: 1
87
+ },
88
+ // 每页条目数
89
+ pageSize: {
90
+ type: Number,
91
+ default: 10
92
+ },
93
+ // 总数据条目数
94
+ total: {
95
+ type: Number,
96
+ default: 0
97
+ },
98
+ // 上一页按钮文案
99
+ prevText: {
100
+ type: String,
101
+ default: ''
102
+ },
103
+ // 下一页按钮文案
104
+ nextText: {
105
+ type: String,
106
+ default: ''
107
+ },
108
+ buttonBgColor: {
109
+ type: String,
110
+ default: '#f5f7fa'
111
+ },
112
+ buttonBorderColor: {
113
+ type: String,
114
+ default: '#dcdfe6'
115
+ },
116
+ // 可选的每页条目数
117
+ pageSizes: {
118
+ type: Array,
119
+ default: () => [10, 20, 30, 40, 50]
120
+ },
121
+ // 布局方式(类似 el-pagination)
122
+ layout: {
123
+ type: String,
124
+ default: 'prev, pager, next'
125
+ },
126
+ // 是否隐藏只有一个页面时的分页控件
127
+ hideOnSinglePage: {
128
+ type: Boolean,
129
+ default: false
130
+ }
131
+ },
132
+ emits: ['update:currentPage', 'update:pageSize', 'current-change', 'size-change'],
133
+ data() {
134
+ return {
135
+ currentPageInput: this.currentPage + ''
136
+ };
137
+ },
138
+ computed: {
139
+ totalPages() {
140
+ return Math.max(1, Math.ceil(this.total / this.pageSize));
141
+ },
142
+ pageSizeIndex() {
143
+ const index = this.pageSizes.findIndex(size => size.value === this.pageSize);
144
+ return index >= 0 ? index : 0;
145
+ },
146
+ pageSizeLabel() {
147
+ const found = this.pageSizes.find(size => size.value === this.pageSize);
148
+ return found?.label || this.pageSize;
149
+ },
150
+ displayedPages() {
151
+ const total = this.totalPages;
152
+ const current = this.currentPage;
153
+
154
+ if (total <= 4) {
155
+ return Array.from({ length: total }, (_, i) => i + 1);
156
+ }
157
+
158
+ const pages = [];
159
+
160
+ // 当前页靠近头部
161
+ if (current <= 2) {
162
+ for (let i = 1; i <= 4; i++) {
163
+ pages.push(i);
164
+ }
165
+ pages.push('...');
166
+ pages.push(total);
167
+ }
168
+ // 当前页在尾部附近
169
+ else if (current >= total - 1) {
170
+ pages.push(1);
171
+ pages.push('...');
172
+ for (let i = total - 3; i <= total; i++) {
173
+ pages.push(i);
174
+ }
175
+ }
176
+ // 中间情况
177
+ else {
178
+ pages.push(1);
179
+ pages.push('...');
180
+ pages.push(current - 1);
181
+ pages.push(current);
182
+ pages.push(current + 1);
183
+ pages.push('...');
184
+ pages.push(total);
185
+ }
186
+
187
+ return pages;
188
+ }
189
+ // 控制是否隐藏
190
+ },
191
+ watch: {
192
+ currentPage(val) {
193
+ this.currentPageInput = val + '';
194
+ }
195
+ },
196
+ methods: {
197
+ handleSizeChange(e) {
198
+ const selected = e.detail.value;
199
+ const size = this.pageSizes[selected]?.value || this.pageSizes[0].value;
200
+ this.$emit('update:pageSize', size);
201
+ this.$emit('size-change', size);
202
+ },
203
+ prev() {
204
+ if (this.currentPage > 1) {
205
+ this.goTo(this.currentPage - 1);
206
+ }
207
+ },
208
+ next() {
209
+ if (this.currentPage < this.totalPages) {
210
+ this.goTo(this.currentPage + 1);
211
+ }
212
+ },
213
+ goTo(page) {
214
+ if (page === '...' || page === this.currentPage) return;
215
+ this.$emit('update:currentPage', page);
216
+ this.$emit('current-change', page);
217
+ },
218
+ onInputPage(e) {
219
+ this.currentPageInput = e.detail.value;
220
+ },
221
+ onConfirmPage(e) {
222
+ const num = parseInt(e.detail.value);
223
+ if (!isNaN(num) && num >= 1 && num <= this.totalPages) {
224
+ this.goTo(num);
225
+ }
226
+ }
227
+ }
228
+ };
229
+ </script>
230
+
231
+ <style lang="scss" scoped>
232
+ .u-pagination {
233
+ display: flex;
234
+ flex-direction: row;
235
+ align-items: center;
236
+ justify-content: space-between;
237
+ flex-wrap: wrap;
238
+ font-size: 14px;
239
+ color: #606266;
240
+
241
+ .u-pagination-total {
242
+ margin-right: 10px;
243
+ }
244
+
245
+ .u-pagination-sizes {
246
+ margin-right: 10px;
247
+ padding: 4px 4px;
248
+ border: 1rpx solid #dcdfe6;
249
+ border-radius: 4px;
250
+ }
251
+
252
+ .u-pagination-btn {
253
+ margin: 0 3px;
254
+ padding: 4px 4px;
255
+ border: 1rpx solid #dcdfe6;
256
+ border-radius: 4px;
257
+ background-color: #f5f7fa;
258
+ &.disabled {
259
+ opacity: 0.5;
260
+ }
261
+ }
262
+
263
+ .u-pagination-item {
264
+ margin: 0 2px;
265
+ padding: 4px 8px;
266
+ border-radius: 4px;
267
+ &.active {
268
+ background-color: #409eff;
269
+ color: white;
270
+ }
271
+ }
272
+
273
+ .u-pagination-jumper {
274
+ width: 40px;
275
+ height: 28px;
276
+ margin: 0 5px;
277
+ padding: 0 5px;
278
+ border: 1rpx solid #dcdfe6;
279
+ border-radius: 4px;
280
+ font-size: 14px;
281
+ }
282
+ }
283
+ </style>
@@ -51,6 +51,7 @@
51
51
  </view>
52
52
  <u-safe-bottom v-if="safeAreaInsetBottom"></u-safe-bottom>
53
53
  </view>
54
+ <slot name="bottom"></slot>
54
55
  </u-transition>
55
56
  </view>
56
57
  </template>