Track the weighbridge mobile-h5 codebase (excluding node_modules, dist, and local .env) so subsequent adaptation tasks can evolve it in-repo. Co-authored-by: Cursor <cursoragent@cursor.com>
149 lines
3.4 KiB
Markdown
149 lines
3.4 KiB
Markdown
# 分页加载实现说明
|
||
|
||
## ✅ 已实现分页加载的页面
|
||
|
||
所有数据列表页面都已实现**滚动分页加载**功能:
|
||
|
||
1. **计划管理** (`/plans`) ✅
|
||
2. **出入库管理** (`/inventory`) ✅
|
||
3. **地磅单管理** (`/weighing`) ✅
|
||
4. **基础资料 - 往来单位** (`/master-data`) ✅
|
||
5. **基础资料 - 货物** (`/master-data`) ✅
|
||
6. **用户管理** (`/user`) ✅
|
||
|
||
## 实现原理
|
||
|
||
### 1. 数据结构
|
||
|
||
每个列表页面都维护两个数据数组:
|
||
- `allData`: 存储从 API 获取的完整数据
|
||
- `tableData`: 当前显示的数据(分页后的数据)
|
||
|
||
### 2. 分页参数
|
||
|
||
- `currentPage`: 当前页码(从 1 开始)
|
||
- `pageSize`: 每页数据量(默认 20 条)
|
||
|
||
### 3. 加载逻辑
|
||
|
||
```typescript
|
||
const loadData = async (reset = false) => {
|
||
// 重置时清空数据
|
||
if (reset) {
|
||
currentPage.value = 1
|
||
allData.value = []
|
||
tableData.value = []
|
||
finished.value = false
|
||
}
|
||
|
||
loading.value = true
|
||
try {
|
||
// 第一页或重置时,重新获取所有数据
|
||
if (reset || currentPage.value === 1) {
|
||
const data = await api.list(params)
|
||
allData.value = data
|
||
}
|
||
|
||
// 分页切片
|
||
const start = (currentPage.value - 1) * pageSize.value
|
||
const end = start + pageSize.value
|
||
const newData = allData.value.slice(start, end)
|
||
|
||
// 追加或替换数据
|
||
if (reset || currentPage.value === 1) {
|
||
tableData.value = newData
|
||
} else {
|
||
tableData.value.push(...newData)
|
||
}
|
||
|
||
// 判断是否加载完成
|
||
if (tableData.value.length >= allData.value.length) {
|
||
finished.value = true
|
||
} else {
|
||
currentPage.value++
|
||
}
|
||
} catch (error) {
|
||
Toast.fail('加载数据失败')
|
||
finished.value = true
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
```
|
||
|
||
### 4. 滚动加载
|
||
|
||
使用 Vant 的 `van-list` 组件实现滚动加载:
|
||
|
||
```vue
|
||
<van-list
|
||
v-model:loading="loading"
|
||
:finished="finished"
|
||
finished-text="没有更多了"
|
||
@load="onLoad"
|
||
>
|
||
<!-- 列表内容 -->
|
||
</van-list>
|
||
```
|
||
|
||
```typescript
|
||
const onLoad = () => {
|
||
if (!finished.value) {
|
||
loadData() // 加载下一页
|
||
}
|
||
}
|
||
```
|
||
|
||
## 使用场景
|
||
|
||
### 初始加载
|
||
```typescript
|
||
onMounted(() => {
|
||
loadData(true) // 重置并加载第一页
|
||
})
|
||
```
|
||
|
||
### 搜索时
|
||
```typescript
|
||
const handleSearch = () => {
|
||
loadData(true) // 重置并重新加载
|
||
}
|
||
```
|
||
|
||
### 增删改后
|
||
```typescript
|
||
// 新增/编辑/删除后
|
||
await api.create(data)
|
||
Toast.success('操作成功')
|
||
loadData(true) // 重置并重新加载
|
||
```
|
||
|
||
## 用户体验
|
||
|
||
1. **首次加载**: 显示第一页数据(20 条)
|
||
2. **滚动到底部**: 自动加载下一页数据
|
||
3. **加载中**: 显示加载状态
|
||
4. **加载完成**: 显示"没有更多了"提示
|
||
5. **搜索**: 重置分页,重新加载数据
|
||
6. **增删改**: 重置分页,刷新列表
|
||
|
||
## 性能优化
|
||
|
||
- **前端分页**: 首次获取所有数据,后续分页在前端完成
|
||
- **按需加载**: 每次只加载 20 条数据,减少 DOM 渲染压力
|
||
- **数据缓存**: `allData` 缓存完整数据,避免重复请求
|
||
|
||
## 注意事项
|
||
|
||
1. **搜索会重置分页**: 搜索时会重新获取数据并重置分页
|
||
2. **增删改会刷新**: 增删改操作后会重置分页并刷新列表
|
||
3. **数据量限制**: 如果数据量非常大(>1000 条),建议后端实现分页接口
|
||
|
||
## 未来优化
|
||
|
||
如果数据量很大,可以考虑:
|
||
1. 后端分页接口(需要后端支持)
|
||
2. 虚拟滚动(使用 `vue-virtual-scroller`)
|
||
3. 数据懒加载(只加载可见区域的数据)
|
||
|