uniapp-dyckui 4.1.1
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/LICENSE +21 -0
- package/README.md +104 -0
- package/dist/assets/style.BFlsbpSj.css +1472 -0
- package/dist/index.cjs.js +1380 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.es.js +1380 -0
- package/dist/index.es.js.map +1 -0
- package/dist/src/components/MyComs/Button/index.d.ts +3 -0
- package/dist/src/components/MyComs/Button/index.vue.d.ts +93 -0
- package/dist/src/components/MyComs/Dialog/index.d.ts +3 -0
- package/dist/src/components/MyComs/Dialog/index.vue.d.ts +65 -0
- package/dist/src/components/MyComs/Divider/index.d.ts +3 -0
- package/dist/src/components/MyComs/Divider/index.vue.d.ts +53 -0
- package/dist/src/components/MyComs/DropdownSelect/dropdownSelect.d.ts +10 -0
- package/dist/src/components/MyComs/DropdownSelect/index.d.ts +4 -0
- package/dist/src/components/MyComs/DropdownSelect/index.vue.d.ts +26 -0
- package/dist/src/components/MyComs/DropdownSelect/type.d.ts +13 -0
- package/dist/src/components/MyComs/DropdownWithBadge/dropdownWithBadge.d.ts +5 -0
- package/dist/src/components/MyComs/DropdownWithBadge/index.d.ts +4 -0
- package/dist/src/components/MyComs/DropdownWithBadge/index.vue.d.ts +26 -0
- package/dist/src/components/MyComs/DropdownWithBadge/type.d.ts +9 -0
- package/dist/src/components/MyComs/FilterDrawer/hasBadge.d.ts +8 -0
- package/dist/src/components/MyComs/FilterDrawer/index.d.ts +5 -0
- package/dist/src/components/MyComs/FilterDrawer/index.vue.d.ts +26 -0
- package/dist/src/components/MyComs/FilterDrawer/type.d.ts +8 -0
- package/dist/src/components/MyComs/FilterDrawer/useFilterDrawer.d.ts +10 -0
- package/dist/src/components/MyComs/InfiniteScroll/index.d.ts +3 -0
- package/dist/src/components/MyComs/InfiniteScroll/index.vue.d.ts +65 -0
- package/dist/src/components/MyComs/Popup/index.d.ts +3 -0
- package/dist/src/components/MyComs/Popup/index.vue.d.ts +119 -0
- package/dist/src/components/MyComs/PullRefresh/index.d.ts +3 -0
- package/dist/src/components/MyComs/PullRefresh/index.vue.d.ts +117 -0
- package/dist/src/components/MyComs/Swiper/index.d.ts +3 -0
- package/dist/src/components/MyComs/Swiper/index.vue.d.ts +79 -0
- package/dist/src/components/MyComs/Toast/index.d.ts +3 -0
- package/dist/src/components/MyComs/Toast/index.vue.d.ts +108 -0
- package/dist/src/components/MyComs/index.d.ts +20 -0
- package/package.json +218 -0
- package/src/components/MyComs/Button/README.md +235 -0
- package/src/components/MyComs/Button/index.ts +3 -0
- package/src/components/MyComs/Button/index.vue +413 -0
- package/src/components/MyComs/Dialog/README.md +160 -0
- package/src/components/MyComs/Dialog/index.ts +2 -0
- package/src/components/MyComs/Dialog/index.vue +275 -0
- package/src/components/MyComs/Divider/README.md +0 -0
- package/src/components/MyComs/Divider/index.ts +2 -0
- package/src/components/MyComs/Divider/index.vue +106 -0
- package/src/components/MyComs/DropdownSelect/README.md +112 -0
- package/src/components/MyComs/DropdownSelect/dropdownSelect.less +75 -0
- package/src/components/MyComs/DropdownSelect/dropdownSelect.ts +59 -0
- package/src/components/MyComs/DropdownSelect/index.ts +4 -0
- package/src/components/MyComs/DropdownSelect/index.vue +88 -0
- package/src/components/MyComs/DropdownSelect/type.ts +15 -0
- package/src/components/MyComs/DropdownWithBadge/README.md +77 -0
- package/src/components/MyComs/DropdownWithBadge/dropdownWithBadge.less +11 -0
- package/src/components/MyComs/DropdownWithBadge/dropdownWithBadge.ts +10 -0
- package/src/components/MyComs/DropdownWithBadge/index.ts +4 -0
- package/src/components/MyComs/DropdownWithBadge/index.vue +39 -0
- package/src/components/MyComs/DropdownWithBadge/type.ts +12 -0
- package/src/components/MyComs/FilterDrawer/filterDrawer.less +117 -0
- package/src/components/MyComs/FilterDrawer/hasBadge.ts +41 -0
- package/src/components/MyComs/FilterDrawer/index.ts +5 -0
- package/src/components/MyComs/FilterDrawer/index.vue +53 -0
- package/src/components/MyComs/FilterDrawer/type.ts +9 -0
- package/src/components/MyComs/FilterDrawer/useFilterDrawer.ts +38 -0
- package/src/components/MyComs/InfiniteScroll/index.ts +2 -0
- package/src/components/MyComs/InfiniteScroll/index.vue +171 -0
- package/src/components/MyComs/Popup/README.md +684 -0
- package/src/components/MyComs/Popup/index.ts +2 -0
- package/src/components/MyComs/Popup/index.vue +835 -0
- package/src/components/MyComs/PullRefresh/README.md +600 -0
- package/src/components/MyComs/PullRefresh/index.ts +2 -0
- package/src/components/MyComs/PullRefresh/index.vue +599 -0
- package/src/components/MyComs/Swiper/README.md +202 -0
- package/src/components/MyComs/Swiper/index.ts +2 -0
- package/src/components/MyComs/Swiper/index.vue +245 -0
- package/src/components/MyComs/Toast/README.md +604 -0
- package/src/components/MyComs/Toast/index.ts +2 -0
- package/src/components/MyComs/Toast/index.vue +372 -0
- package/src/components/MyComs/index.ts +33 -0
|
@@ -0,0 +1,600 @@
|
|
|
1
|
+
# 🎯 PullRefresh 下拉刷新组件
|
|
2
|
+
|
|
3
|
+
<div align="center">
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+
|
|
10
|
+
功能强大、灵活易用的下拉刷新与无限滚动组件
|
|
11
|
+
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## ✨ 特性
|
|
17
|
+
|
|
18
|
+
- 🎯 **智能下拉刷新**:支持触摸下拉触发刷新,释放可刷新提示
|
|
19
|
+
- 📜 **无限滚动加载**:滚动到底部自动加载更多数据
|
|
20
|
+
- 🎨 **丰富的状态显示**:下拉距离、释放可刷新、刷新中、刷新完成等状态
|
|
21
|
+
- 📱 **响应式设计**:完美适配各种屏幕尺寸
|
|
22
|
+
- ⚡ **高性能优化**:节流处理,平滑动画效果
|
|
23
|
+
- 🛠️ **高度可配置**:支持自定义文本、阈值、动画等
|
|
24
|
+
- 🔄 **独立功能控制**:可独立启用/禁用下拉刷新和无限滚动
|
|
25
|
+
- 🎭 **事件回调完善**:提供完整的生命周期事件
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 📚 目录
|
|
30
|
+
|
|
31
|
+
- [特性](#-特性)
|
|
32
|
+
- [快速开始](#-快速开始)
|
|
33
|
+
- [API 文档](#-api-文档)
|
|
34
|
+
- [使用示例](#-使用示例)
|
|
35
|
+
- [最佳实践](#-最佳实践)
|
|
36
|
+
- [常见问题](#-常见问题)
|
|
37
|
+
- [更新日志](#-更新日志)
|
|
38
|
+
- [许可证](#-许可证)
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 🚀 快速开始
|
|
43
|
+
|
|
44
|
+
### 安装
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# 复制组件到项目中
|
|
48
|
+
cp src/components/MyComs/PullRefresh src/your-project/components/
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 基础用法
|
|
52
|
+
|
|
53
|
+
```vue
|
|
54
|
+
<template>
|
|
55
|
+
<PullRefresh
|
|
56
|
+
:loading="loading"
|
|
57
|
+
:refreshLoading="refreshLoading"
|
|
58
|
+
:hasMore="hasMore"
|
|
59
|
+
:error="error"
|
|
60
|
+
@refresh="onRefresh"
|
|
61
|
+
@loadMore="onLoadMore"
|
|
62
|
+
@retry="onRetry"
|
|
63
|
+
>
|
|
64
|
+
<div class="list-container">
|
|
65
|
+
<div v-for="item in listData" :key="item.id" class="list-item">
|
|
66
|
+
{{ item.title }}
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
</PullRefresh>
|
|
70
|
+
</template>
|
|
71
|
+
|
|
72
|
+
<script setup lang="ts">
|
|
73
|
+
import { ref } from 'vue'
|
|
74
|
+
import PullRefresh from '@/components/MyComs/PullRefresh/index.vue'
|
|
75
|
+
|
|
76
|
+
const listData = ref([])
|
|
77
|
+
const loading = ref(false)
|
|
78
|
+
const refreshLoading = ref(false)
|
|
79
|
+
const hasMore = ref(true)
|
|
80
|
+
const error = ref(false)
|
|
81
|
+
|
|
82
|
+
// 下拉刷新
|
|
83
|
+
const onRefresh = async () => {
|
|
84
|
+
refreshLoading.value = true
|
|
85
|
+
// 模拟异步请求
|
|
86
|
+
await new Promise(resolve => setTimeout(resolve, 1500))
|
|
87
|
+
listData.value = []
|
|
88
|
+
for (let i = 1; i <= 10; i++) {
|
|
89
|
+
listData.value.push({ id: i, title: `刷新后的列表项${i}` })
|
|
90
|
+
}
|
|
91
|
+
hasMore.value = true
|
|
92
|
+
refreshLoading.value = false
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// 加载更多
|
|
96
|
+
const onLoadMore = async () => {
|
|
97
|
+
if (loading.value || !hasMore.value) return
|
|
98
|
+
loading.value = true
|
|
99
|
+
await new Promise(resolve => setTimeout(resolve, 1500))
|
|
100
|
+
const startIndex = listData.value.length + 1
|
|
101
|
+
for (let i = startIndex; i < startIndex + 10; i++) {
|
|
102
|
+
listData.value.push({ id: i, title: `列表项${i}` })
|
|
103
|
+
}
|
|
104
|
+
if (listData.value.length >= 30) {
|
|
105
|
+
hasMore.value = false
|
|
106
|
+
}
|
|
107
|
+
loading.value = false
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// 重试加载
|
|
111
|
+
const onRetry = () => {
|
|
112
|
+
error.value = false
|
|
113
|
+
onLoadMore()
|
|
114
|
+
}
|
|
115
|
+
</script>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 使用示例代码片段
|
|
119
|
+
```vue
|
|
120
|
+
<template>
|
|
121
|
+
<PullRefresh
|
|
122
|
+
:loading="loading"
|
|
123
|
+
:refreshLoading="refreshLoading"
|
|
124
|
+
:hasMore="hasMore"
|
|
125
|
+
:error="error"
|
|
126
|
+
:threshold="30"
|
|
127
|
+
:refreshThreshold="40"
|
|
128
|
+
:refreshText="'下拉刷新'"
|
|
129
|
+
:releaseText="'释放可刷新'"
|
|
130
|
+
:refreshingText="'正在刷新...'"
|
|
131
|
+
:refreshSuccessText="'刷新成功'"
|
|
132
|
+
:loadingText="'加载中...'"
|
|
133
|
+
:errorText="'加载失败'"
|
|
134
|
+
:noMoreText="'没有更多数据了'"
|
|
135
|
+
@refresh="onRefresh"
|
|
136
|
+
@loadMore="onLoadMore"
|
|
137
|
+
@retry="onRetry"
|
|
138
|
+
>
|
|
139
|
+
<div class="list-container">
|
|
140
|
+
<div v-for="item in listData" :key="item.id" class="list-item">
|
|
141
|
+
{{ item.title }}
|
|
142
|
+
</div>
|
|
143
|
+
</div>
|
|
144
|
+
</PullRefresh>
|
|
145
|
+
</template>
|
|
146
|
+
|
|
147
|
+
<script setup>
|
|
148
|
+
import { ref } from 'vue'
|
|
149
|
+
|
|
150
|
+
const listData = ref([])
|
|
151
|
+
const loading = ref(false)
|
|
152
|
+
const refreshLoading = ref(false)
|
|
153
|
+
const hasMore = ref(true)
|
|
154
|
+
const error = ref(false)
|
|
155
|
+
|
|
156
|
+
// 初始化数据
|
|
157
|
+
const initData = () => {
|
|
158
|
+
for (let i = 1; i <= 10; i++) {
|
|
159
|
+
listData.value.push({ id: i, title: `列表项${i}` })
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// 下拉刷新
|
|
164
|
+
const onRefresh = async () => {
|
|
165
|
+
refreshLoading.value = true
|
|
166
|
+
// 模拟异步请求
|
|
167
|
+
await new Promise(resolve => setTimeout(resolve, 1500))
|
|
168
|
+
// 清空并重新加载数据
|
|
169
|
+
listData.value = []
|
|
170
|
+
for (let i = 1; i <= 10; i++) {
|
|
171
|
+
listData.value.push({ id: i, title: `刷新后的列表项${i}` })
|
|
172
|
+
}
|
|
173
|
+
hasMore.value = true
|
|
174
|
+
refreshLoading.value = false
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// 加载更多
|
|
178
|
+
const onLoadMore = async () => {
|
|
179
|
+
if (loading.value || !hasMore.value) return
|
|
180
|
+
loading.value = true
|
|
181
|
+
// 模拟异步请求
|
|
182
|
+
await new Promise(resolve => setTimeout(resolve, 1500))
|
|
183
|
+
// 添加新数据
|
|
184
|
+
const startIndex = listData.value.length + 1
|
|
185
|
+
for (let i = startIndex; i < startIndex + 10; i++) {
|
|
186
|
+
listData.value.push({ id: i, title: `列表项${i}` })
|
|
187
|
+
}
|
|
188
|
+
// 模拟数据加载完毕
|
|
189
|
+
if (listData.value.length >= 30) {
|
|
190
|
+
hasMore.value = false
|
|
191
|
+
}
|
|
192
|
+
loading.value = false
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// 重试加载
|
|
196
|
+
const onRetry = () => {
|
|
197
|
+
error.value = false
|
|
198
|
+
onLoadMore()
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// 初始化
|
|
202
|
+
initData()
|
|
203
|
+
</script>
|
|
204
|
+
|
|
205
|
+
<style scoped>
|
|
206
|
+
.list-container {
|
|
207
|
+
padding: 16px;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.list-item {
|
|
211
|
+
padding: 12px;
|
|
212
|
+
margin-bottom: 8px;
|
|
213
|
+
background-color: #f5f5f5;
|
|
214
|
+
border-radius: 8px;
|
|
215
|
+
}
|
|
216
|
+
</style>
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## 📚 API 文档
|
|
222
|
+
|
|
223
|
+
### 🔧 Props 属性
|
|
224
|
+
|
|
225
|
+
| 参数名 | 类型 | 默认值 | 说明 |
|
|
226
|
+
|--------|------|--------|------|
|
|
227
|
+
| `loading` | `Boolean` | `false` | 无限滚动加载状态 |
|
|
228
|
+
| `refreshLoading` | `Boolean` | `false` | 下拉刷新加载状态 |
|
|
229
|
+
| `hasMore` | `Boolean` | `true` | 是否还有更多数据 |
|
|
230
|
+
| `error` | `Boolean` | `false` | 加载失败状态 |
|
|
231
|
+
| `threshold` | `Number` | `30` | 触发无限滚动的阈值距离(像素) |
|
|
232
|
+
| `refreshThreshold` | `Number` | `40` | 下拉刷新触发阈值(像素) |
|
|
233
|
+
| `throttleTime` | `Number` | `200` | 节流时间(毫秒) |
|
|
234
|
+
| `loadingText` | `String` | `'加载中...'` | 加载中提示文本 |
|
|
235
|
+
| `errorText` | `String` | `'加载失败'` | 加载失败提示文本 |
|
|
236
|
+
| `retryText` | `String` | `'点击重试'` | 重试按钮文本 |
|
|
237
|
+
| `noMoreText` | `String` | `'没有更多数据了'` | 无更多数据提示文本 |
|
|
238
|
+
| `refreshText` | `String` | `'下拉刷新'` | 下拉刷新提示文本 |
|
|
239
|
+
| `releaseText` | `String` | `'释放可刷新'` | 释放可刷新提示文本 |
|
|
240
|
+
| `refreshingText` | `String` | `'正在刷新...'` | 正在刷新提示文本 |
|
|
241
|
+
| `refreshSuccessText` | `String` | `'刷新成功'` | 刷新成功提示文本 |
|
|
242
|
+
| `refreshErrorText` | `String` | `'刷新失败'` | 刷新失败提示文本 |
|
|
243
|
+
| `useWindowScroll` | `Boolean` | `false` | 是否使用窗口作为滚动容器 |
|
|
244
|
+
| `enableInfiniteScroll` | `Boolean` | `false` | 是否启用无限滚动 |
|
|
245
|
+
| `enableRefresh` | `Boolean` | `true` | 是否启用下拉刷新 |
|
|
246
|
+
|
|
247
|
+
### 🎯 事件 Events
|
|
248
|
+
|
|
249
|
+
| 事件名 | 回调参数 | 说明 |
|
|
250
|
+
|--------|----------|------|
|
|
251
|
+
| `refresh` | - | 下拉刷新触发时调用 |
|
|
252
|
+
| `loadMore` | - | 滚动到底部触发加载更多时调用 |
|
|
253
|
+
| `retry` | - | 点击加载失败重试按钮时调用 |
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## 💡 使用示例
|
|
258
|
+
|
|
259
|
+
### 🎨 自定义样式示例
|
|
260
|
+
|
|
261
|
+
```vue
|
|
262
|
+
<template>
|
|
263
|
+
<PullRefresh
|
|
264
|
+
v-model:loading="loading"
|
|
265
|
+
v-model:refreshLoading="refreshLoading"
|
|
266
|
+
:hasMore="hasMore"
|
|
267
|
+
:error="error"
|
|
268
|
+
refreshText="下拉刷新数据"
|
|
269
|
+
releaseText="释放立即刷新"
|
|
270
|
+
refreshingText="刷新中..."
|
|
271
|
+
refreshSuccessText="刷新成功!"
|
|
272
|
+
loadingText="加载中..."
|
|
273
|
+
noMoreText="没有更多了"
|
|
274
|
+
@refresh="handleRefresh"
|
|
275
|
+
@loadMore="handleLoadMore"
|
|
276
|
+
>
|
|
277
|
+
<view class="custom-list">
|
|
278
|
+
<view v-for="item in dataList" :key="item.id" class="custom-item">
|
|
279
|
+
<image :src="item.avatar" class="avatar" />
|
|
280
|
+
<view class="content">
|
|
281
|
+
<text class="title">{{ item.title }}</text>
|
|
282
|
+
<text class="desc">{{ item.description }}</text>
|
|
283
|
+
</view>
|
|
284
|
+
</view>
|
|
285
|
+
</view>
|
|
286
|
+
</PullRefresh>
|
|
287
|
+
</template>
|
|
288
|
+
|
|
289
|
+
<script setup lang="ts">
|
|
290
|
+
import { ref } from 'vue'
|
|
291
|
+
|
|
292
|
+
const dataList = ref([])
|
|
293
|
+
const loading = ref(false)
|
|
294
|
+
const refreshLoading = ref(false)
|
|
295
|
+
const hasMore = ref(true)
|
|
296
|
+
const error = ref(false)
|
|
297
|
+
|
|
298
|
+
const handleRefresh = async () => {
|
|
299
|
+
refreshLoading.value = true
|
|
300
|
+
try {
|
|
301
|
+
// 模拟API调用
|
|
302
|
+
const response = await fetch('/api/data?refresh=true')
|
|
303
|
+
const newData = await response.json()
|
|
304
|
+
dataList.value = newData
|
|
305
|
+
error.value = false
|
|
306
|
+
} catch (err) {
|
|
307
|
+
error.value = true
|
|
308
|
+
} finally {
|
|
309
|
+
refreshLoading.value = false
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const handleLoadMore = async () => {
|
|
314
|
+
if (loading.value || !hasMore.value) return
|
|
315
|
+
|
|
316
|
+
loading.value = true
|
|
317
|
+
try {
|
|
318
|
+
const response = await fetch(`/api/data?offset=${dataList.value.length}`)
|
|
319
|
+
const newData = await response.json()
|
|
320
|
+
dataList.value.push(...newData)
|
|
321
|
+
|
|
322
|
+
if (newData.length < 10) {
|
|
323
|
+
hasMore.value = false
|
|
324
|
+
}
|
|
325
|
+
error.value = false
|
|
326
|
+
} catch (err) {
|
|
327
|
+
error.value = true
|
|
328
|
+
} finally {
|
|
329
|
+
loading.value = false
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
</script>
|
|
333
|
+
|
|
334
|
+
<style scoped>
|
|
335
|
+
.custom-list {
|
|
336
|
+
padding: 20rpx;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
.custom-item {
|
|
340
|
+
display: flex;
|
|
341
|
+
align-items: center;
|
|
342
|
+
padding: 20rpx;
|
|
343
|
+
margin-bottom: 20rpx;
|
|
344
|
+
background: white;
|
|
345
|
+
border-radius: 16rpx;
|
|
346
|
+
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
.avatar {
|
|
350
|
+
width: 80rpx;
|
|
351
|
+
height: 80rpx;
|
|
352
|
+
border-radius: 50%;
|
|
353
|
+
margin-right: 20rpx;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
.content {
|
|
357
|
+
flex: 1;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
.title {
|
|
361
|
+
font-size: 32rpx;
|
|
362
|
+
font-weight: 600;
|
|
363
|
+
color: #333;
|
|
364
|
+
margin-bottom: 8rpx;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
.desc {
|
|
368
|
+
font-size: 28rpx;
|
|
369
|
+
color: #666;
|
|
370
|
+
line-height: 1.4;
|
|
371
|
+
}
|
|
372
|
+
</style>
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### 🔧 仅下拉刷新模式
|
|
376
|
+
|
|
377
|
+
```vue
|
|
378
|
+
<template>
|
|
379
|
+
<PullRefresh
|
|
380
|
+
:enableRefresh="true"
|
|
381
|
+
:enableInfiniteScroll="false"
|
|
382
|
+
:refreshLoading="refreshLoading"
|
|
383
|
+
@refresh="handleRefresh"
|
|
384
|
+
>
|
|
385
|
+
<view class="content">
|
|
386
|
+
<text>这里是静态内容,只需要下拉刷新</text>
|
|
387
|
+
</view>
|
|
388
|
+
</PullRefresh>
|
|
389
|
+
</template>
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
### 🔧 仅无限滚动模式
|
|
393
|
+
|
|
394
|
+
```vue
|
|
395
|
+
<template>
|
|
396
|
+
<PullRefresh
|
|
397
|
+
:enableRefresh="false"
|
|
398
|
+
:enableInfiniteScroll="true"
|
|
399
|
+
:loading="loading"
|
|
400
|
+
:hasMore="hasMore"
|
|
401
|
+
:error="error"
|
|
402
|
+
@loadMore="handleLoadMore"
|
|
403
|
+
@retry="handleRetry"
|
|
404
|
+
>
|
|
405
|
+
<view class="feed-list">
|
|
406
|
+
<view v-for="item in feedList" :key="item.id" class="feed-item">
|
|
407
|
+
<text>{{ item.content }}</text>
|
|
408
|
+
</view>
|
|
409
|
+
</view>
|
|
410
|
+
</PullRefresh>
|
|
411
|
+
</template>
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
## 🎯 最佳实践
|
|
417
|
+
|
|
418
|
+
### 📱 场景选择指南
|
|
419
|
+
|
|
420
|
+
| 使用场景 | 推荐配置 | 说明 |
|
|
421
|
+
|----------|----------|------|
|
|
422
|
+
| **新闻列表** | `enableRefresh: true`, `enableInfiniteScroll: true` | 完整的内容刷新和加载体验 |
|
|
423
|
+
| **聊天记录** | `enableRefresh: true`, `enableInfiniteScroll: false` | 只支持下拉刷新获取最新消息 |
|
|
424
|
+
| **商品列表** | `enableRefresh: false`, `enableInfiniteScroll: true` | 只支持滚动加载更多商品 |
|
|
425
|
+
| **静态内容** | `enableRefresh: true`, `enableRefresh: false` | 纯刷新功能 |
|
|
426
|
+
|
|
427
|
+
### ⚡ 性能优化建议
|
|
428
|
+
|
|
429
|
+
1. **合理设置阈值**
|
|
430
|
+
```vue
|
|
431
|
+
<!-- 推荐:移动端合适的阈值 -->
|
|
432
|
+
<PullRefresh
|
|
433
|
+
:refreshThreshold="60"
|
|
434
|
+
:threshold="50"
|
|
435
|
+
/>
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
2. **节流时间优化**
|
|
439
|
+
```vue
|
|
440
|
+
<!-- 推荐:根据内容复杂度调整节流时间 -->
|
|
441
|
+
<PullRefresh
|
|
442
|
+
:throttleTime="100"
|
|
443
|
+
:enableInfiniteScroll="true"
|
|
444
|
+
/>
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
3. **懒加载内容**
|
|
448
|
+
```vue
|
|
449
|
+
<!-- 推荐:使用v-if延迟渲染非可见内容 -->
|
|
450
|
+
<PullRefresh>
|
|
451
|
+
<div v-for="item in visibleItems" :key="item.id">
|
|
452
|
+
{{ item.content }}
|
|
453
|
+
</div>
|
|
454
|
+
</PullRefresh>
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
### 🛠️ 常见陷阱避免
|
|
458
|
+
|
|
459
|
+
1. **状态管理**
|
|
460
|
+
```vue
|
|
461
|
+
<!-- 错误:直接在事件中处理复杂逻辑 -->
|
|
462
|
+
@refresh="() => { loading = true; fetchData(); loading = false; }"
|
|
463
|
+
|
|
464
|
+
<!-- 正确:使用async/await处理异步逻辑 -->
|
|
465
|
+
@refresh="handleRefresh"
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
2. **内存泄漏预防**
|
|
469
|
+
```vue
|
|
470
|
+
<script setup lang="ts">
|
|
471
|
+
import { onUnmounted } from 'vue'
|
|
472
|
+
|
|
473
|
+
onUnmounted(() => {
|
|
474
|
+
// 清理定时器、事件监听器等
|
|
475
|
+
clearTimeout(timer)
|
|
476
|
+
})
|
|
477
|
+
</script>
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
3. **iOS兼容处理**
|
|
481
|
+
```vue
|
|
482
|
+
<!-- 推荐:处理iOS Safari的橡皮筋效果 -->
|
|
483
|
+
<template>
|
|
484
|
+
<PullRefresh
|
|
485
|
+
:useWindowScroll="false"
|
|
486
|
+
:enableRefresh="true"
|
|
487
|
+
>
|
|
488
|
+
<!-- 内容 -->
|
|
489
|
+
</PullRefresh>
|
|
490
|
+
</template>
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
## ❓ 常见问题
|
|
496
|
+
|
|
497
|
+
### 🔍 FAQ
|
|
498
|
+
|
|
499
|
+
**Q: 如何禁用下拉刷新功能?**
|
|
500
|
+
```vue
|
|
501
|
+
<PullRefresh :enableRefresh="false" />
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
**Q: 如何自定义刷新动画?**
|
|
505
|
+
```vue
|
|
506
|
+
<!-- 通过CSS类名覆盖默认样式 -->
|
|
507
|
+
<PullRefresh class="custom-refresh">
|
|
508
|
+
<!-- 内容 -->
|
|
509
|
+
</PullRefresh>
|
|
510
|
+
|
|
511
|
+
<style>
|
|
512
|
+
.custom-refresh .refresh-animation {
|
|
513
|
+
/* 自定义动画样式 */
|
|
514
|
+
}
|
|
515
|
+
</style>
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
**Q: 在uni-app小程序中如何使用?**
|
|
519
|
+
```vue
|
|
520
|
+
<!-- 完全兼容,无需特殊配置 -->
|
|
521
|
+
<PullRefresh
|
|
522
|
+
:loading="loading"
|
|
523
|
+
:hasMore="hasMore"
|
|
524
|
+
@loadMore="loadMore"
|
|
525
|
+
>
|
|
526
|
+
<view class="list">
|
|
527
|
+
<view v-for="item in list" :key="item.id">
|
|
528
|
+
{{ item.title }}
|
|
529
|
+
</view>
|
|
530
|
+
</view>
|
|
531
|
+
</PullRefresh>
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
**Q: 如何处理网络错误?**
|
|
535
|
+
```vue
|
|
536
|
+
<script setup>
|
|
537
|
+
const handleRefresh = async () => {
|
|
538
|
+
try {
|
|
539
|
+
await fetchData()
|
|
540
|
+
error.value = false
|
|
541
|
+
} catch (err) {
|
|
542
|
+
error.value = true
|
|
543
|
+
uni.showToast({
|
|
544
|
+
title: '网络错误,请重试',
|
|
545
|
+
icon: 'error'
|
|
546
|
+
})
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
</script>
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
**Q: 滚动不触发加载更多?**
|
|
553
|
+
- 检查容器高度是否足够(内容需要超过一屏)
|
|
554
|
+
- 确认 `enableInfiniteScroll` 为 `true`
|
|
555
|
+
- 检查 `hasMore` 状态是否正确
|
|
556
|
+
|
|
557
|
+
### 🐛 问题排查
|
|
558
|
+
|
|
559
|
+
1. **下拉刷新不生效**
|
|
560
|
+
- 检查触摸事件是否被其他元素阻止
|
|
561
|
+
- 确认容器高度和内容高度
|
|
562
|
+
- 检查阈值设置是否合理
|
|
563
|
+
|
|
564
|
+
2. **无限滚动不触发**
|
|
565
|
+
- 确认滚动容器高度
|
|
566
|
+
- 检查 `hasMore` 和 `loading` 状态
|
|
567
|
+
- 验证阈值设置
|
|
568
|
+
|
|
569
|
+
3. **动画效果异常**
|
|
570
|
+
- 检查CSS冲突
|
|
571
|
+
- 确认浏览器兼容性
|
|
572
|
+
- 验证transform属性使用
|
|
573
|
+
|
|
574
|
+
---
|
|
575
|
+
|
|
576
|
+
## 📄 更新日志
|
|
577
|
+
|
|
578
|
+
### v1.0.0 (2024-01-01)
|
|
579
|
+
- ✨ 初始版本发布
|
|
580
|
+
- 🎯 支持下拉刷新和无限滚动
|
|
581
|
+
- 🎨 丰富的状态显示和自定义文本
|
|
582
|
+
- 📱 响应式设计适配
|
|
583
|
+
- ⚡ 性能优化和节流处理
|
|
584
|
+
- 🛠️ 完整的TypeScript类型支持
|
|
585
|
+
|
|
586
|
+
---
|
|
587
|
+
|
|
588
|
+
## 📄 许可证
|
|
589
|
+
|
|
590
|
+
MIT License
|
|
591
|
+
|
|
592
|
+
---
|
|
593
|
+
|
|
594
|
+
<div align="center">
|
|
595
|
+
|
|
596
|
+
**如果这个组件对您有帮助,请给个 ⭐ Star!**
|
|
597
|
+
|
|
598
|
+
Made with ❤️ by Your Team
|
|
599
|
+
|
|
600
|
+
</div>
|