前言
在现今的移动应用开发中,微信小程序已经成为了一个备受欢迎的平台。然而,随着应用的复杂性增加,数据的管理和加载成为了一个问题。本文将探讨微信小程序中的一个关键概念:封装分页器,它是提升小程序性能和用户体验的不可或缺的工具之一。通过深入了解分页器的工作原理以及如何正确地封装和使用它,大家将能够更好地管理和加载数据,从而为你的小程序带来更出色的性能和用户体验。
实现效果
封装公共方法
wxml
文件
首先,在视图层(WXML
)中,创建了一个包含分页相关元素的自定义组件,包括总数据条数的展示、每页显示条数的下拉框、当前页码的展示、上一页和下一页的按钮、前往页码的输入框。
html
<view class="mainBox">
<view class="paginationBox">
<view class="totalBox">共 {{total}} 条</view>
<view class="selectPageBox">
<picker bindchange="handlePageSizeChange" value="{{pageSizeIndex}}" range="{{pageSizes}}">
<view>{{pageSizes[pageSizeIndex]}}条/页</view>
</picker>
</view>
<view class="contantBox">
<view style="color:{{pageNum<=1 ? 'rgb(194,201,213)' : 'rgb(25, 137, 250)'}}" class="updownPageBox" bindtap="prevPage">
<van-icon name="arrow-left" />
</view>
<view class="pageBox">{{pageNum}}</view>
<view style="color:{{pageNum >= (total / pageSize) ? 'rgb(194,201,213)' : 'rgb(25, 137, 250)'}}" class="updownPageBox" bindtap="nextPage">
<van-icon name="arrow" />
</view>
</view>
<view class="intBox">
<text>前往</text>
<input class="intConBox" bindconfirm="handlePageConfirm" type="number" />
<text>页</text>
</view>
</view>
</view>
js
文件
- 在组件的属性(
properties
)中定义了三个属性:total
、pageSize
、pageNum
,用于控制分页的相关数据。其中,total
表示总数据条数,pageSize
表示每页显示条数,pageNum
表示当前页码。同时,在pageNum
属性中定义了一个观察者函数,用于在pageNum
属性变化时更新数据中的pageNum
; - 定义了数据(
data
)中的一些变量,包括每页显示条数选项pageSizes
和默认选中的每页显示条数pageSizeIndex
; - 在
methods
中定义了一些方法,实现了分页功能:prevPage
方法:用于点击上一页按钮,减小pageNum
,但要确保pageNum
大于1
,触发自定义事件pageChange
传递当前页码信息;nextPage
方法:用于点击下一页按钮,增加pageNum
,但要确保pageNum
小于最大页数,触发自定义事件pageChange
传递当前页码信息;handlePageSizeChange
方法:用于选择每页显示条数的下拉框,更新pageSize
和pageSizeIndex
,触发自定义事件pageSizeChange
传递每页显示条数信息;handlePageConfirm
方法:用于页码输入框的确认操作,获取输入的页码并转换为整数,确保输入的页码在有效范围内,然后更新pageNum
,触发自定义事件pageChange
传递当前页码信息;- 自定义事件
pageChange
和pageSizeChange
可以在使用该组件的父组件中监听,以便在分页信息发生变化时执行相应的逻辑操作。
js
Component({
properties: {
total: { // 总数据条数
type: Number, // 数据类型为数字
value: 0 // 默认值为0
},
pageSize: { // 每页显示条数
type: Number, // 数据类型为数字
value: 10 // 默认值为10
},
pageNum: { // 当前页码
type: Number, // 数据类型为数字
value: 1, // 默认值为1
observer(newVal) { // 当pageNum属性变化时触发的观察者函数
this.setData({
pageNum: newVal // 更新数据中的pageNum
});
}
}
},
data: {
pageSizes: [5, 10, 15, 20], // 每页显示条数选项
pageSizeIndex: 1, // 默认选中的每页显示条数
},
methods: {
// 上一页
prevPage() {
if (this.data.pageNum > 1) { // 如果当前页码大于1
this.setData({
pageNum: this.data.pageNum - 1 // 减小pageNum
});
this.triggerEvent('pageChange', { // 触发名为'pageChange'的自定义事件,传递当前页码信息
page: this.data.pageNum
});
} else {
wx.showToast({
title: '已经是第一页',
icon: 'none'
});
}
},
// 下一页
nextPage() {
const maxPage = Math.ceil(this.data.total / this.data.pageSize); // 计算最大页数
if (this.data.pageNum < maxPage) { // 如果当前页码小于最大页数
this.setData({
pageNum: this.data.pageNum + 1 // 增加pageNum
});
this.triggerEvent('pageChange', { // 触发名为'pageChange'的自定义事件,传递当前页码信息
page: this.data.pageNum
});
} else {
wx.showToast({
title: '已经是最后一页',
icon: 'none'
});
}
},
// 每页显示条数下拉框
handlePageSizeChange(event) {
const index = event.detail.value; // 获取选择的索引
const pageSize = this.data.pageSizes[index]; // 获取对应索引的每页显示条数
this.setData({
pageSize, // 更新pageSize
pageSizeIndex: index, // 更新pageSizeIndex
});
this.triggerEvent('pageSizeChange', { // 触发名为'pageSizeChange'的自定义事件,传递每页显示条数信息
pageSize
});
},
// 页码输入框
handlePageConfirm(event) {
const inputValue = event.detail.value.trim(); // 获取去掉前后空格的输入值
if (inputValue === '') {
// 如果输入值为空,则不执行查询操作
return;
}
const page = parseInt(inputValue); // 获取输入的页码并转换为整数
const maxPage = Math.ceil(this.data.total / this.data.pageSize); // 计算最大页数
if (page >= 1 && page <= maxPage) { // 如果输入的页码有效
this.setData({
pageNum: page // 更新pageNum
});
this.triggerEvent('pageChange', { // 触发名为'pageChange'的自定义事件,传递当前页码信息
page
});
} else {
wx.showToast({
title: '请输入有效页数',
icon: 'none'
});
}
}
}
});
wxss
文件
css
.paginationBox {
margin-top: 20rpx;
font-size: 28rpx;
display: flex;
align-items: center;
justify-content: flex-end;
}
.totalBox {
color: #606266;
height: 48rpx;
line-height: 48rpx;
}
.selectPageBox {
border: 2rpx solid #dcdfe6;
margin: 0rpx 14rpx;
color: #606266;
padding: 0rpx 18rpx;
text-align: center;
height: 44rpx;
line-height: 44rpx;
border-radius: 4rpx;
}
.contantBox {
display: flex;
}
.updownPageBox,
.pageBox {
padding: 0rpx 14rpx;
color: rgb(25, 137, 250);
background-color: rgb(244, 244, 245);
height: 48rpx;
line-height: 48rpx;
border-radius: 4rpx;
}
.pageBox {
margin: 0rpx 10rpx;
}
.intBox {
margin-left: 14rpx;
color: #606266;
display: flex;
align-items: center;
}
.intBox input {
height: 44rpx;
line-height: 44rpx;
min-height: 44rpx;
}
.intConBox {
border: 2rpx solid #dcdfe6;
border-radius: 4rpx;
width: 60rpx;
text-align: center;
margin: 0rpx 6rpx;
}
app.json
文件全局引用
json
"usingComponents": {
"pagination": "./components/pagination/index"
},
任意文件使用
wxml
文件
html
<view class="tableBox">
<scroll-view scroll-x>
<view class="table">
<view class="tableRow">
<text class="tableNavBox">Header 1</text>
<text class="tableNavBox">Header 2</text>
<text class="tableNavBox">Header 3</text>
</view>
<view class="tableRow" wx:for="{{list}}" wx:key="index">
<text class="tableCellBox">{{item.ffzt}}</text>
<text class="tableCellBox">{{item.fdjccrq}}</text>
<text class="tableCellBox">{{item.gl}}</text>
</view>
</view>
</scroll-view>
<!-- 分页组件 -->
<view>
<pagination total="{{total}}" pageSize="{{pageSize}}" currentPage="{{currentPage}}" bind:pageChange="handlePageChange" bind:pageSizeChange="handlePageSizeChange">
</pagination>
</view>
</view>
js
文件
js
var app = getApp(); // 获取小程序应用实例
Page({
data: {
list: [], // 存储数据列表
pageNum: 1, // 当前页码
total: 0, // 数据总数
pageSize: 10, // 每页显示条数
},
onLoad: function () {
this.tableOn(); // 在页面加载时调用tableOn函数
},
tableOn() {
let that = this; // 缓存this,以在回调函数中使用
// 发起网络请求获取数据
wx.request({
url: app.API_URL + 'yourUrl', // 请求的URL
data: {
rows: {
pageNum: that.data.pageNum, // 当前页码
pageSize: that.data.pageSize, // 每页显示条数
},
},
success: function (res) {
that.setData({
list: res.data.list, // 更新数据列表
total: res.data.pagejx.areaNum, // 更新数据总数
});
},
});
},
// 处理分页组件页码变化事件
handlePageChange(event) {
this.setData({
pageNum: event.detail.page, // 更新当前页码
});
this.tableOn(); // 重新加载数据
},
// 处理分页组件每页显示条数变化事件
handlePageSizeChange(event) {
this.setData({
pageNum: 1, // 重置页码为1
pageSize: event.detail.pageSize, // 更新每页显示条数
});
this.tableOn(); // 重新加载数据
},
});