前言
实战篇内容参考:
1、分页组件开发 https://blog.csdn.net/qq_41756580/article/details/103273569
2、开发过程遇到问题。
3、异步处理方法,Promise的应用请移步至“微信小程序|入门篇
”。
1、分页组件pagination
分析该分页组件的所具有的功能:
- 上一页、下一页的切换;
- 上一页、下一页边界问题;
- 点击中间页,可以直接选择跳转的页数;
- 页数跳转时,需要与父组件进行通信(通知下一页页数、是否为有效页数)。
2、pagination代码分析
2.1 wxml骨架文件
- 骨架结构简单左右按钮+中间
view
包裹的页码text
; - 使用
hidden
属性隐藏的页码选择页面,主要是一个遮罩层view
+wx:for
渲染的页面数。
<!--components/pagination/pagination.wxml-->
<view class="page-control">
<view class="page-control-btns">
<view class="page-btn {{prevBtnDis?'btn-disabled':''}}" bindtap="prevPage">上一页</view>
<view class="page-number" bindtap="shopPagePopup"><text>{{index}}</text>/<text>{{total}}</text></view>
<view class="page-btn {{nextBtnDis?'btn-disabled':''}}" bindtap="nextPage">下一页</view>
</view>
<view class="page-container" hidden="{{!pageMask}}">
<view class="page-mask" bindtap="hidePagePopup"></view>
<view class="page-popup">
<view class="page-popup-box">
<view class="page-line" wx:for="{{total}}" wx:for-index="idx" data-index="{{idx+1}}" bindtap="changePage">第{{item+1}}页</view>
</view>
</view>
</view>
</view>
2.2 wxss样式
/* components/pagination/pagination.wxss */
view,text,image{
padding: 0;
margin: 0;
box-sizing: border-box;
}
.page-control{
width: 100%;
}
.page-control .page-control-btns{
width: 100%;
padding: 20rpx 0;
display: flex;
align-items: center;
justify-content: space-around;
}
.page-control .page-control-btns .page-number{
width: 20%;
text-align: center;
color: #333;
}
.page-control .page-control-btns .page-number:active{
background-color: #ddd;
}
.page-control .page-control-btns .page-btn{
width: 30%;
padding: 15rpx 20rpx;
font-size: 30rpx;
background-color: #0099CC;
color: #fff;
border-radius: 10rpx;
text-align: center;
}
.page-control .page-control-btns .page-btn:active{
opacity: .5;
}
.page-control .page-control-btns .btn-disabled{
background-color: #ddd;
color: #999;
}
.page-container{
position: fixed;
top: 0rpx;
left: 0rpx;
width: 100%;
height: 100%;
z-index: 999;
}
.page-mask{
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
background-color: rgba(0,0,0,0.5);
}
.page-popup{
width: 100%;
height: 100%;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
}
.page-popup-box{
width: 60%;
margin: 0 auto;
background-color: #fff;
height: 60%;
border-radius: 10rpx;
z-index: 9999;
overflow: auto;
}
.page-line{
width: 100%;
height: 80rpx;
line-height: 80rpx;
padding: 0rpx 20rpx;
border-bottom: 1rpx solid #e2e2e2;
}
.page-line:active{
background-color: #ddd;
}
2.3 pagination的逻辑文件
参考文章的思路很混乱,我按照自己思路重构了一下。都是按照上面的分析走的,主要是让当前页数在1和total的时候,不可以点击出界的按钮。也就是当页数发生变化时,变化之后(包括上一页、下一页和指定页数)的页数一定是可以加载的页数。
// components/pagination/pagination.js
Component({
/**
* 组件的属性列表
*/
properties: {
currentIndex: { //当前页码
type: Number,
value: 1
},
totalPage: {
type: Number
}
},
/**
* 组件的初始数据
*/
data: {
index: 1,
total: 10,
pageMask: false,
prevBtnDis: true,
nextBtnDis: false
},
/**
* 组件的方法列表
*/
lifetimes: {
// 在组件实例进入页面节点树时执行
attached: function () {
this.setData({
index: this.properties.currentIndex,
total: this.properties.totalPage
})
}
},
methods: {
// 设置异步请求之后的页面、总记录数
setPage(index, total){
this.setData({
index,
total
})
},
//每次改变页码就调用该函数
triggerParent: function () {
// 通知父组件当前加载的页数
// 自定义组件向父组件传值
const option = {
currentIndex: this.data.index
};
// pagingChange 自定义名称事件,父组件中使用
this.triggerEvent('pagingChange', option)
},
//开启页码弹窗
showPagePopUp: function () {
this.setData({
pageMask: true
})
},
//关闭页码弹窗
hidePagePopUp: function () {
this.setData({
pageMask: false
})
},
//更改页码点击事件
onChangePage: function (e) {
//console.log("更改页码事件:",e);
this.setData({
pageMask: false,
index: e.currentTarget.dataset.index //点击的页数
})
// 先判断当前页数,是否需要更新disabled的状态
this.updateBtnDis();
this.triggerParent();
},
//上一页点击事件
prevPage: function () {
if(this.data.index <= 1) return;
let num = this.data.index - 1;
this.setData({
index: num
})
this.triggerParent();
// 更新按钮状态
this.updateBtnDis();
},
//下一页点击事件
nextPage: function () {
if(this.data.index >= this.data.total) return;
let num = this.data.index + 1;
this.setData({
index: num
})
this.triggerParent();
// 更新按钮状态
this.updateBtnDis();
},
//判断按钮是否为disabled
updateBtnDis: function () {
let index = this.data.index;
let total = this.data.total;
if(index == total && index == 1){ // 都为起始页和总页数都为1
this.setData({
nextBtnDis: true,
prevBtnDis: true
})
}else if (index == total) { // 最后一页
this.setData({
nextBtnDis: true
})
} else if (index == 1){ // 第一页
this.setData({
prevBtnDis: true
})
}else{
this.setData({
prevBtnDis: false
})
this.setData({
nextBtnDis: false
})
}
}
}
})