本文主要针对支付宝小程序的tabs标签页切换进行自定义。
大家可以发现官方文档是有点小缺陷的,可以支持页面左右滑动,但是要固定高度而且要写到acss样式文件里。不支持页面滑动的话高度可以自适应。但是还是有点小问题的哦。况且不支持滑动显得还是不是很友好。
下面粘上我的代码。自定义实现tabs页切换和页面左右切换。
page.axml
<scroll-view scroll-x="true" class="nav" scroll-with-animation="{{true}}">
<block a:for="{{tabs}}" a:key="{{index}}">
<view class="nav-item">
<view class="{{activeTab == index ?'active':''}}" data-current="{{index}}" onTap="handleTabClick">{{item.title}}</view>
</view>
</block>
</scroll-view>
<swiper class="tab-box " current="{{activeTab}}" duration="300" onChange="handleTabChange">
<swiper-item a:for="{{tabsType}}" a:key="{{index}}" class="tab-content">
<contract-item ref = "{{item.ref}}" status = "{{item.status}}" onShowNullData = "onShowNullData"/>
</swiper-item>
</swiper>
page.acss
.nav {
height: 80rpx;
width: 100%;
box-sizing: border-box;
overflow: hidden;
line-height: 76rpx;
background: #FFFFFF;
font-size: 14px;
white-space: nowrap;
display: flex;
box-sizing: border-box;
}
.nav::-webkit-scrollbar {
display: none;
}
.nav-item {
flex-shrink: 0;
-webkit-box-flex: 0;
flex-grow: 0;
width: 33.333333%;
height: 76rpx;
text-align: center;
}
.active{
display: inline-block;
color:#4884EE;
border-bottom: 2px solid #4884EE;
}
.tab-box{
height: 750px !important;
background:#F5F5F5;
box-sizing: border-box;
}
.tab-content{
margin-top: 1rpx;
overflow-y: auto;
display: flex;
flex-direction: column;
}
page.json
{
"defaultTitle": "订单管理",
"pullRefresh": true,
"usingComponents": {
"contract-item": "./contract-item/contract-item"
}
}
page.js
Page({
data: {
tabsType: [//标签数组
{ ref: "page0",status: '1'},
{ ref: "page1",status: '2'},
{ ref: "page2",status: '3'}
],
loadFlags: 0x0000,//各tab是否加载
tabs: [
{ title: '待审核' },
{ title: '已通过' },
{ title: '已拒绝' }
],
activeTab: 0,
footer: false,
},
page0(ref) {
this.page0 = ref;
},
page1(ref) {
this.page1 = ref;
},
page2(ref) {
this.page2 = ref;
},
onLoad() {
this.setData({
loadFlags: 0x0001
});
},
onPullDownRefresh() {
this.onRefresh();
},
onReachBottom() {
if (this.data.activeTab === 0) {
this.page0.onLoadMore();
}else if(this.data.activeTab === 1){
this.page1.onLoadMore();
}else{
this.page2.onLoadMore();
}
},
//标签切换
handleTabClick(e) {
this.setData({
activeTab: e.currentTarget.dataset.current
})
this.onCalculate();
},
//手势滑动
handleTabChange(e) {
console.log(e)
var cur = e.detail.current;
if (this.data.activeTab == cur) {
return false;
} else {
this.setData({
activeTab: cur
})
}
this.onCalculate();
},
//我在这里注释一下,怕以后在看的时候自己再费时间理解
onCalculate: function () {
//次方运算 1 2 4
let tempFlag = Math.pow(2, this.data.activeTab);
// 按位与
// 0x0001 & 0x0001 = 0x0001 1 已加载
// 0x0001 & 0x0010 = 0x0000 0 未加载
// 0x0001 & 0x0100 = 0x0000 0 未加载
let hasLoaded = this.data.loadFlags & tempFlag;
if (!hasLoaded) {//未加载
this.onRefresh();//加载数据
//获取当前加载状态 0x0001 已加载
let curFlags = this.data.loadFlags;
//修改状态
this.setData({
// 按位或
// 0x0001 | 0x0010 = 0x0011
// 0x0001 | 0x0100 = 0x0111
loadFlags: (curFlags | tempFlag),
});
}
},
onRefresh: function () {
if (this.data.activeTab === 0) {
this.page0.onRefresh();
}else if(this.data.activeTab === 1){
this.page1.onRefresh();
}else{
this.page2.onRefresh();
}
},
contract-item.axml
<view>
<scroll-view scroll-y onScrollToLower="onLoadMore">
<list>
<block a:for="{{list}}">
<list-item
align="{{item.align}}"
index="{{index}}"
onClick="onItemClick"
key="items-{{index}}"
last="{{index === (list.length - 1)}}"
data-id="{{item.id}}"
>
<view></view>
</list-item>
</block>
</list>
</scroll-view>
</view>
contract-item.acss
.am-list-item {
padding: 0;
}
.am-list-content {
padding: 0;
}
contract-item.js
const api = require('../../../../request.js')
import pageStatus, { onRetry } from '../../../../page-status/page-status.js'
const app = getApp()
Component({
mixins: [],
data: {
page0: null,
page1: null,
page2: null,
list: [],
pageNum: 1,
pageSize: 10,
total: 0,
scrollHeight:my.getSystemInfoSync().windowHeight-44,
},
props: {
status: '1',
onShowNullData: () => {},
},
didMount() {
if (this.props.status === '1') {
this.onRefresh();
}
},
didUpdate() {},
didUnmount() {},
methods: {
/* 下拉刷新 */
onRefresh: function () {
this.setData({
pageNum: 1
})
this.onFetchData();
},
// 上拉加载
onLoadMore: function() {
console.log('上啦加载了');
// 不分页不加载、加载完毕不加载
if (this.data.total > this.data.list.length) {
this.setData({
pageNum: this.data.pageNum + 1
})
this.onFetchData();
}
},
// 获取数据
onFetchData: function() {
const currentPageStatus = pageStatus(this);
my.showNavigationBarLoading();
if (app.globalData.networkFailed) {//网络监听
currentPageStatus.nonetwork();
my.stopPullDownRefresh();
my.hideNavigationBarLoading();
} else {
var url = `/dayan/scf/user/contract/list/${this.props.status}?pageNum=${this.data.pageNum}&pageSize=${this.data.pageSize}`
api.http(url,'GET',{},success=>{
if (this.data.pageNum === 1) {//第一页
this.setData({
list: success.data,
total: success.total
})
} else {//第n页
this.setData({
list: this.data.list.concat(success.data),
total: success.total
})
}
if (this.data.list.length === 0) {
currentPageStatus.empty();
} else {
currentPageStatus.finish();
}
my.hideNavigationBarLoading();
this.onShowNullData();
}, fail=>{
currentPageStatus.error();
my.hideNavigationBarLoading();
});
}
},
onItemClick(e) {
let id = e.target.dataset.id;
let dest = `./contract-detail/contract-detail?id=${id}`;
my.navigateTo({
url: dest,
})
},
onRetry() {
console.log('刷新网络操作')
this.onRefresh();
},
},
});
contract-item.json
{
"component": true,
"usingComponents": {
"list-item": "mini-antui/es/list/list-item/index",
"list": "mini-antui/es/list/index"
}
}
component的js文件数据部分(onFetchData)是我自己定义的缺省页面及网络状态监测,请使用的小主自行修改为自己封装的内容
觉得有帮助的给小姐姐带个赞吧。感谢~