unibest分页组件:z-paging高级用法
还在为uniapp列表分页开发而烦恼?数据加载、下拉刷新、上拉加载、空状态处理等问题是否让你头疼不已?本文将深入解析unibest框架中z-paging组件的高级用法,让你彻底掌握企业级分页开发技巧。通过本文你将学会:- z-paging核心配置与最佳实践- 多种数据源对接方案(RESTful API、GraphQL、本地数据)- 高级功能:自定义加载动画、复杂空状态处理、多Tab切换...
·
unibest分页组件:z-paging高级用法
还在为uniapp列表分页开发而烦恼?数据加载、下拉刷新、上拉加载、空状态处理等问题是否让你头疼不已?本文将深入解析unibest框架中z-paging组件的高级用法,让你彻底掌握企业级分页开发技巧。
通过本文你将学会:
- z-paging核心配置与最佳实践
- 多种数据源对接方案(RESTful API、GraphQL、本地数据)
- 高级功能:自定义加载动画、复杂空状态处理、多Tab切换
- 性能优化与常见问题解决方案
一、z-paging核心架构解析
z-paging作为uniapp生态中最强大的分页组件,其架构设计遵循MVVM模式,提供了完整的生命周期管理。
1.1 基础配置示例
<template>
<z-paging
ref="pagingRef"
v-model:data="dataList"
:fixed="false"
:auto-show-back-to-top="true"
:auto-scroll-to-top-when-reload="true"
@query="queryList"
>
<template #default="{ item }">
<view class="item">
<text>{{ item.title }}</text>
<text>{{ item.createTime }}</text>
</view>
</template>
<template #loading>
<u-loading mode="circle" />
</template>
<template #empty>
<u-empty mode="data" />
</template>
</z-paging>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import type { ZPaging } from 'z-paging'
const pagingRef = ref<ZPaging>()
const dataList = ref<any[]>([])
// 分页查询方法
const queryList = async (pageNo: number, pageSize: number) => {
try {
const params = { pageNo, pageSize }
const response = await api.getList(params)
// 必须返回数组和总条数
return {
data: response.data.list,
total: response.data.total
}
} catch (error) {
// 错误处理
pagingRef.value?.complete(false)
throw error
}
}
</script>
二、多数据源接入方案
2.1 RESTful API对接
// 使用alova进行请求封装
import { createAlova } from 'alova'
import { uniRequestAdapter } from '@alova/adapter-uniapp'
const alovaInstance = createAlova({
baseURL: 'https://api.example.com',
requestAdapter: uniRequestAdapter(),
responded: response => response.json()
})
// 分页请求Hook
export const usePagingRequest = (url: string) => {
const request = (pageNo: number, pageSize: number) => {
return alovaInstance.Get(url, {
params: { pageNo, pageSize }
})
}
return { request }
}
2.2 GraphQL分页方案
// GraphQL分页查询
const queryListGraphQL = async (pageNo: number, pageSize: number) => {
const query = `
query GetList($page: Int!, $size: Int!) {
items(page: $page, size: $size) {
list {
id
title
content
createTime
}
total
}
}
`
const variables = { page: pageNo, size: pageSize }
const response = await graphqlClient.request(query, variables)
return {
data: response.items.list,
total: response.items.total
}
}
2.3 本地数据分页
// 本地大数据集分页
const localDataPaging = (pageNo: number, pageSize: number, allData: any[]) => {
const start = (pageNo - 1) * pageSize
const end = start + pageSize
const pageData = allData.slice(start, end)
return {
data: pageData,
total: allData.length
}
}
三、高级功能实战
3.1 自定义加载动画与状态
<template>
<z-paging
ref="pagingRef"
v-model:data="dataList"
:loading-more-enabled="true"
:hide-empty-view="true"
@query="queryList"
>
<!-- 自定义加载状态 -->
<template #loading>
<view class="custom-loading">
<u-loading-icon size="36" color="#2979ff" />
<text class="loading-text">拼命加载中...</text>
</view>
</template>
<!-- 自定义加载更多 -->
<template #loadingMoreDefault>
<view class="load-more-default">
<text>上拉加载更多</text>
</view>
</template>
<template #loadingMoreLoading>
<view class="load-more-loading">
<u-loading-icon size="24" />
<text>加载中...</text>
</view>
</template>
<template #loadingMoreNoMore>
<view class="load-more-nomore">
<text>没有更多数据了</text>
</view>
</template>
</z-paging>
</template>
<style scoped>
.custom-loading {
display: flex;
flex-direction: column;
align-items: center;
padding: 40rpx 0;
}
.loading-text {
margin-top: 20rpx;
color: #999;
font-size: 28rpx;
}
.load-more-default,
.load-more-loading,
.load-more-nomore {
padding: 30rpx 0;
text-align: center;
color: #999;
font-size: 28rpx;
}
</style>
3.2 复杂空状态处理
<template>
<z-paging
ref="pagingRef"
v-model:data="dataList"
:hide-empty-view="true"
@query="queryList"
>
<template #empty>
<view class="empty-container">
<!-- 网络错误空状态 -->
<template v-if="networkError">
<u-empty mode="network" />
<button class="retry-btn" @click="retry">重试</button>
</template>
<!-- 搜索无结果 -->
<template v-else-if="isSearching">
<u-empty mode="search" />
<text class="empty-text">换个关键词试试吧</text>
</template>
<!-- 默认空状态 -->
<template v-else>
<u-empty mode="data" />
<text class="empty-text">暂无数据</text>
</template>
</view>
</template>
</z-paging>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const networkError = ref(false)
const isSearching = ref(false)
const retry = () => {
networkError.value = false
pagingRef.value?.reload()
}
</script>
3.3 多Tab切换分页
<template>
<view class="container">
<!-- Tab切换 -->
<u-tabs
:list="tabList"
:current="currentTab"
@change="tabChange"
/>
<!-- 分页组件 -->
<z-paging
ref="pagingRef"
v-model:data="dataList"
:auto="false"
@query="queryList"
>
<!-- 内容渲染 -->
</z-paging>
</view>
</template>
<script lang="ts" setup>
import { ref, watch } from 'vue'
const tabList = [
{ name: '全部', value: 'all' },
{ name: '进行中', value: 'processing' },
{ name: '已完成', value: 'completed' }
]
const currentTab = ref('all')
const dataList = ref<any[]>([])
const pagingRef = ref()
// Tab切换监听
watch(currentTab, (newVal) => {
// 切换Tab时重置分页
pagingRef.value?.reload()
})
const queryList = async (pageNo: number, pageSize: number) => {
const params = {
pageNo,
pageSize,
status: currentTab.value
}
const response = await api.getListByStatus(params)
return {
data: response.data.list,
total: response.data.total
}
}
const tabChange = (index: number) => {
currentTab.value = tabList[index].value
}
</script>
四、性能优化策略
4.1 数据缓存优化
// 使用Pinia进行分页数据缓存
import { defineStore } from 'pinia'
export const usePagingCache = defineStore('paging-cache', {
state: () => ({
cache: new Map<string, any>()
}),
actions: {
setCache(key: string, data: any) {
this.cache.set(key, {
data,
timestamp: Date.now()
})
},
getCache(key: string, maxAge: number = 5 * 60 * 1000) {
const cached = this.cache.get(key)
if (!cached) return null
if (Date.now() - cached.timestamp > maxAge) {
this.cache.delete(key)
return null
}
return cached.data
}
}
})
4.2 虚拟列表优化
<template>
<z-paging
ref="pagingRef"
v-model:data="dataList"
use-virtual-list
:virtual-list-height="800"
:virtual-item-size="100"
@query="queryList"
>
<template #default="{ item, index }">
<view class="virtual-item" :style="{ height: '100px' }">
<text>{{ item.title }}</text>
</view>
</template>
</z-paging>
</template>
4.3 图片懒加载优化
<template>
<z-paging
ref="pagingRef"
v-model:data="dataList"
@query="queryList"
>
<template #default="{ item }">
<view class="item">
<u-image
:src="item.image"
mode="aspectFill"
lazy-load
:fade="true"
duration="450"
/>
<text>{{ item.title }}</text>
</view>
</template>
</z-paging>
</template>
五、常见问题解决方案
5.1 数据重复问题
// 使用Set去重
const handleData = (newData: any[], oldData: any[]) => {
const combined = [...oldData, ...newData]
const uniqueData = Array.from(
new Set(combined.map(item => item.id))
).map(id => combined.find(item => item.id === id))
return uniqueData
}
5.2 页码混乱处理
// 防止快速切换导致的页码混乱
let currentPage = 1
let isRequesting = false
const queryList = async (pageNo: number) => {
if (isRequesting) return
isRequesting = true
currentPage = pageNo
try {
const response = await api.getList({ pageNo })
// 检查是否为当前请求的页码
if (currentPage === pageNo) {
return {
data: response.data.list,
total: response.data.total
}
}
} finally {
isRequesting = false
}
}
5.3 错误重试机制
// 带重试机制的分页请求
const queryListWithRetry = async (pageNo: number, retryCount = 3) => {
for (let i = 0; i < retryCount; i++) {
try {
const response = await api.getList({ pageNo })
return {
data: response.data.list,
total: response.data.total
}
} catch (error) {
if (i === retryCount - 1) throw error
// 等待一段时间后重试
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)))
}
}
}
六、最佳实践总结
6.1 配置推荐表
| 配置项 | 推荐值 | 说明 |
|---|---|---|
auto |
false |
手动控制加载时机 |
use-cache |
true |
启用缓存提高性能 |
hide-empty-view |
true |
自定义空状态显示 |
loading-more-enabled |
true |
启用上拉加载更多 |
auto-clean-list-when-reload |
true |
重新加载时清空列表 |
6.2 性能优化 checklist
- 启用虚拟列表对于长列表
- 实现图片懒加载
- 使用数据缓存机制
- 优化网络请求频率
- 合理设置分页大小(建议20-50条)
6.3 错误处理策略
// 统一的错误处理
const handlePagingError = (error: any) => {
console.error('分页请求错误:', error)
// 网络错误
if (error.code === 'NETWORK_ERROR') {
showToast('网络连接失败,请检查网络设置')
}
// 服务器错误
else if (error.code >= 500) {
showToast('服务器繁忙,请稍后重试')
}
// 其他错误
else {
showToast('请求失败,请重试')
}
// 通知分页组件请求失败
pagingRef.value?.complete(false)
}
通过本文的深入学习,相信你已经掌握了z-paging在unibest框架中的高级用法。在实际开发中,根据具体业务场景选择合适的配置和优化策略,将大幅提升应用的性能和用户体验。
记得在实践中不断总结经验,形成适合自己的最佳实践方案。Happy coding!
更多推荐
所有评论(0)