uview-plus 3.4.29 → 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,8 @@
1
+ ## 3.4.30(2025-05-16)
2
+ feat: 新增pagination分页器组件
3
+
4
+ feat: popup新增bottom插槽适用类似关闭按钮与内容区域分离的场景
5
+
1
6
  ## 3.4.29(2025-05-15)
2
7
  fix: 修复table2横向滚动样式
3
8
 
@@ -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>
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.29",
5
+ "version": "3.4.30",
6
6
  "description": "零云®uview-plus已兼容vue3,全面的组件和便捷的工具会让您信手拈来,如鱼得水。",
7
7
  "keywords": [
8
8
  "uview",