uview-plus 3.4.67 → 3.4.68

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,6 @@
1
+ ## 3.4.68(2025-08-03)
2
+ feat: 新增pull-refresh下拉刷新组件
3
+
1
4
  ## 3.4.67(2025-08-02)
2
5
  feat: number-box支持disabledBgColor参数
3
6
 
@@ -0,0 +1,265 @@
1
+ <template>
2
+ <view
3
+ class="u-pull-refresh"
4
+ @touchstart="onTouchStart"
5
+ @touchmove="onTouchMove"
6
+ @touchend="onTouchEnd"
7
+ @touchcancel="onTouchEnd"
8
+ >
9
+ <!-- 下拉刷新区域 -->
10
+ <view
11
+ class="refresh-area"
12
+ :style="{ height: refreshDistance + 'px' }"
13
+ :class="{ refreshing: isRefreshing }"
14
+ >
15
+ <!-- 不同状态的插槽 -->
16
+ <slot
17
+ v-if="refreshStatus === 'pull'"
18
+ name="pull"
19
+ :distance="refreshDistance"
20
+ :threshold="threshold"
21
+ >
22
+ <!-- 默认下拉状态 -->
23
+ <view class="refresh-content">
24
+ <view class="refresh-indicator">
25
+ <view class="arrow"></view>
26
+ </view>
27
+ <text class="refresh-text">下拉刷新</text>
28
+ </view>
29
+ </slot>
30
+
31
+ <slot
32
+ v-else-if="refreshStatus === 'release'"
33
+ name="release"
34
+ :distance="refreshDistance"
35
+ :threshold="threshold"
36
+ >
37
+ <!-- 默认释放状态 -->
38
+ <view class="refresh-content">
39
+ <view class="refresh-indicator">
40
+ <view class="arrow rotate"></view>
41
+ </view>
42
+ <text class="refresh-text">释放刷新</text>
43
+ </view>
44
+ </slot>
45
+
46
+ <slot
47
+ v-else-if="refreshStatus === 'refreshing'"
48
+ name="refreshing"
49
+ >
50
+ <!-- 默认刷新中状态 -->
51
+ <view class="refresh-content">
52
+ <view class="refresh-indicator">
53
+ <view class="spinner"></view>
54
+ </view>
55
+ <text class="refresh-text">正在刷新...</text>
56
+ </view>
57
+ </slot>
58
+ </view>
59
+
60
+ <!-- 内容区域 -->
61
+ <view
62
+ class="refresh-content-wrapper"
63
+ :style="{ transform: `translateY(${contentTranslateY}px)` }"
64
+ >
65
+ <slot></slot>
66
+ </view>
67
+ </view>
68
+ </template>
69
+
70
+ <script>
71
+ export default {
72
+ name: 'u-pull-refresh',
73
+ props: {
74
+ // 是否正在刷新
75
+ refreshing: {
76
+ type: Boolean,
77
+ default: false
78
+ },
79
+ // 下拉刷新阈值
80
+ threshold: {
81
+ type: Number,
82
+ default: 50
83
+ },
84
+ // 阻尼系数
85
+ damping: {
86
+ type: Number,
87
+ default: 0.4
88
+ },
89
+ // 最大下拉距离
90
+ maxDistance: {
91
+ type: Number,
92
+ default: 100
93
+ }
94
+ },
95
+ data() {
96
+ return {
97
+ // 下拉刷新相关
98
+ isRefreshing: false,
99
+ refreshStatus: 'pull', // pull, release, refreshing
100
+ refreshDistance: 0,
101
+ startY: 0,
102
+ currentY: 0,
103
+ touching: false,
104
+
105
+ // 动画相关
106
+ contentTranslateY: 0
107
+ }
108
+ },
109
+ watch: {
110
+ refreshing: {
111
+ handler(newVal) {
112
+ if (!newVal) {
113
+ this.finishRefresh()
114
+ } else {
115
+ this.startRefresh()
116
+ }
117
+ }
118
+ }
119
+ },
120
+ methods: {
121
+ // 触摸开始
122
+ onTouchStart(e) {
123
+ if (this.isRefreshing) return
124
+
125
+ this.touching = true
126
+ this.startY = e.touches[0].pageY
127
+ this.currentY = this.startY
128
+ this.refreshStatus = 'pull'
129
+ },
130
+
131
+ // 触摸移动
132
+ onTouchMove(e) {
133
+ if (!this.touching || this.isRefreshing) return
134
+
135
+ this.currentY = e.touches[0].pageY
136
+ const diff = this.currentY - this.startY
137
+
138
+ // 只有在顶部且下拉时才触发下拉刷新
139
+ if (diff > 0) {
140
+ this.refreshDistance = Math.min(diff * this.damping, this.maxDistance)
141
+ this.contentTranslateY = this.refreshDistance
142
+
143
+ // 更新状态
144
+ if (this.refreshDistance >= this.threshold) {
145
+ this.refreshStatus = 'release'
146
+ } else {
147
+ this.refreshStatus = 'pull'
148
+ }
149
+ }
150
+ },
151
+
152
+ // 触摸结束
153
+ onTouchEnd() {
154
+ if (!this.touching) return
155
+
156
+ this.touching = false
157
+
158
+ if (this.refreshDistance >= this.threshold && !this.isRefreshing) {
159
+ // 触发刷新
160
+ this.startRefresh()
161
+ this.$emit('refresh')
162
+ } else {
163
+ // 回弹
164
+ this.resetRefresh()
165
+ }
166
+ },
167
+
168
+ // 开始刷新
169
+ startRefresh() {
170
+ this.isRefreshing = true
171
+ this.refreshStatus = 'refreshing'
172
+ this.refreshDistance = this.threshold
173
+ this.contentTranslateY = this.threshold
174
+ },
175
+
176
+ // 完成刷新
177
+ finishRefresh() {
178
+ this.isRefreshing = false
179
+ this.refreshStatus = 'pull'
180
+ this.resetRefresh()
181
+ },
182
+
183
+ // 重置刷新状态
184
+ resetRefresh() {
185
+ this.refreshDistance = 0
186
+ this.contentTranslateY = 0
187
+ }
188
+ }
189
+ }
190
+ </script>
191
+
192
+ <style scoped lang="scss">
193
+ .u-pull-refresh {
194
+ position: relative;
195
+ height: 100%;
196
+ overflow: hidden;
197
+ }
198
+
199
+ .refresh-area {
200
+ position: absolute;
201
+ left: 0;
202
+ right: 0;
203
+ top: 0;
204
+ display: flex;
205
+ align-items: flex-end;
206
+ justify-content: center;
207
+ overflow: hidden;
208
+ transition: height 0.2s ease-out;
209
+ }
210
+
211
+ .refresh-content-wrapper {
212
+ height: 100%;
213
+ transition: transform 0.2s ease-out;
214
+ }
215
+
216
+ .refresh-content {
217
+ display: flex;
218
+ flex-direction: column;
219
+ align-items: center;
220
+ justify-content: center;
221
+ width: 100%;
222
+ padding-bottom: 10px;
223
+ }
224
+
225
+ .refresh-indicator {
226
+ width: 24px;
227
+ height: 24px;
228
+ display: flex;
229
+ align-items: center;
230
+ justify-content: center;
231
+ margin-bottom: 8px;
232
+ }
233
+
234
+ .arrow {
235
+ width: 12px;
236
+ height: 12px;
237
+ border-left: 2px solid #666;
238
+ border-bottom: 2px solid #666;
239
+ transform: rotate(-45deg);
240
+ transition: transform 0.2s;
241
+ }
242
+
243
+ .arrow.rotate {
244
+ transform: rotate(135deg);
245
+ }
246
+
247
+ .spinner {
248
+ width: 16px;
249
+ height: 16px;
250
+ border: 2px solid #f3f3f3;
251
+ border-top: 2px solid #666;
252
+ border-radius: 50%;
253
+ animation: spin 1s linear infinite;
254
+ }
255
+
256
+ @keyframes spin {
257
+ 0% { transform: rotate(0deg); }
258
+ 100% { transform: rotate(360deg); }
259
+ }
260
+
261
+ .refresh-text {
262
+ font-size: 14px;
263
+ color: #666;
264
+ }
265
+ </style>
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.67",
5
+ "version": "3.4.68",
6
6
  "description": "零云®uview-plus已兼容vue3,全面的组件和便捷的工具会让您信手拈来,如鱼得水。",
7
7
  "keywords": [
8
8
  "uview",