注意要点
1、通过uni.getSystemInfo获取设备具体高度,定义swiper的高度,将swiper撑开
2、利用scroll-view视图容器的@scrolltolower属性实现触底加载
3、点击tab切换也会触发swiper的@change属性,点击tab只需更改tabIndex (当前所处的tab下标),其他操作在是旁人的@change属性中进行处理即可
详细代码参考
<template>
<view class="container">
<!-- 状态栏 -->
<view class="public-statusBar"></view>
<!-- 状态栏end -->
<!-- 自定义导航栏 -->
<view class="public-navBar">
<view @click="back" class="public-navLeft" open-type="switchTab">
<uni-icons type="arrowleft" style="margin-left: -20rpx;" color="#000" size="26" />
</view>
<view class="public-navMiddle">列表页</view>
</view>
<!-- 自定义导航栏end -->
<!-- tab切换 -->
<view class="tab-titBar">
<view v-for="(tit, index) in tabTit" :key="index" class="tab-titList jui-flex-center" :class="{ 'tab-titHover': index == tabIndex }" @click="tabChange(index)">
{{ tit }}
<text></text>
</view>
</view>
<!-- tab切换end -->
<!-- 列表 -->
<view class="list-bar">
<swiper class="swiper" :style="{ height: swiperHeight + 'px' }" :current="tabIndex" @change="swiperTab">
<!-- 全部 -->
<swiper-item>
<scroll-view scroll-y="true" @scrolltolower="reachBottom">
<!-- jui-h28顶部间隔,使用padding或margin内容撑不满整页会出现滚动条 -->
<view class="jui-h28"></view>
<!-- 暂无记录 -->
<view v-if="status=='noData'" class="empty-bar">
<image class="empty-image" src="../../static/icons/empty_icon.png" mode="widthFix"></image>
<view class="empty-text">暂无报警记录</view>
</view>
<!-- 暂无记录 -->
<block v-else>
<view class="public-bar list-con" v-for="(item, index) in listItem" :key="index">
<text>全部{{item}}</text>
</view>
<view class="example-body" v-if="status!='noData'"><uni-load-more color="#007AFF" :status="status" /></view>
</block>
</scroll-view>
</swiper-item>
<!-- 全部end -->
<!-- 未处理 -->
<swiper-item>
<scroll-view scroll-y="true" @scrolltolower="reachBottom">
<!-- jui-h28顶部间隔,使用padding或margin内容撑不满整页会出现滚动条 -->
<view class="jui-h28"></view>
<!-- 未处理暂无记录 -->
<view v-if="untreatedStatus=='noData'" class="empty-bar">
<view class="empty-text">暂无未处理报警记录</view>
</view>
<!-- 未处理暂无记录 -->
<block v-else>
<view class="public-bar list-con" v-for="(item, index) in untreatedListItem" :key="index">
<text>未处理{{item}}</text>
</view>
<view class="example-body" v-if="untreatedStatus!='noData'"><uni-load-more color="#007AFF" :status="untreatedStatus" /></view>
</block>
</scroll-view>
</swiper-item>
<!-- 未处理end -->
<!-- 已处理 -->
<swiper-item>
<scroll-view scroll-y="true" @scrolltolower="reachBottom">
<!-- jui-h28顶部间隔,使用padding或margin内容撑不满整页会出现滚动条 -->
<view class="jui-h28"></view>
<!-- 已处理暂无记录 -->
<view v-if="dealStatus=='noData'" class="empty-bar">
<view class="empty-text">暂无已处理报警记录</view>
</view>
<!-- 已处理暂无记录 -->
<block v-else>
<view class="public-bar list-con" v-for="(item, index) in dealListItem" :key="index">
<text>已处理{{item}}</text>
</view>
<view class="example-body" v-if="dealStatus!='noData'"><uni-load-more color="#007AFF" :status="dealStatus" /></view>
</block>
</scroll-view>
</swiper-item>
<!-- 已处理end -->
</swiper>
</view>
</view>
</template>
<script>
export default {
data() {
return {
swiperHeight:'',
tabTit: ['全部', '未处理', '已处理'],
tabIndex: 0,
listItem:[],//全部列表
untreatedListItem:[],//未处理列表
dealListItem:[],//已处理列表
pageSize:10, //每页数量
pageNum:1, //全部当前页面
untreatedPageNum:1, //未处理当前页面
dealPageNum:1, //已处理当前页面
status: 'loading',//全部加载状态
untreatedStatus: 'loading',//未处理加载状态
dealStatus: 'loading',//已处理加载状态
}
},
//下拉刷新
onPullDownRefresh() {
//this.reset();
if( this.tabIndex == 0 ){
this.pageNum = 1;
this.getList(this.pageNum);
}else if( this.tabIndex == 1 ){
this.untreatedPageNum = 1;
this.getList(this.untreatedPageNum,0);
}else{
this.dealPageNum = 1;
this.getList(this.dealPageNum,1);
}
},
onLoad:function(options){
uni.getSystemInfo({
success: (res) => {
this.swiperHeight= res.windowHeight - res.statusBarHeight - 50 - 44;//定义swipr高度,44为导航栏高度,50为tab轮播高度,statusBarHeight状态栏高度
}
});
},
mounted() {
this.getList(this.pageNum); //获取列表,默认获取全部,tab切换时调取对应数据
},
methods: {
//返回上一页
back(){
uni.navigateBack({
delta: 1
});
},
//上拉加载
reachBottom(e){
if( this.tabIndex == 0 && this.status == 'more'){
this.pageNum += 1;
this.getList(this.pageNum);
}else if( this.tabIndex == 1 && this.untreatedStatus == 'more'){
this.untreatedPageNum += 1;
this.getList(this.untreatedPageNum,0);
}else if( this.tabIndex == 2 && this.dealStatus == 'more'){
this.dealPageNum += 1;
this.getList(this.dealPageNum,1);
}
},
//获取列表信息
getList(pageNum,bjDone=''){
var param = {}
if( pageNum == 1 ){
if( this.tabIndex == 0 ){
this.listItem = [];
}else if( this.tabIndex == 1){
this.untreatedListItem = [];
}else{
this.dealListItem = [];
}
}
this.$api.request({
url: this.$api.接口名,
data: param,
onSuccess: data => {
//console.log('data',data);
if( data.code == 0 ){//接口调取成功
if( data.total>0 ){
if( this.tabIndex == 0 ){//全部
this.listItem = this.listItem.concat(data.rows);
}else if( this.tabIndex == 1){//未处理
this.untreatedListItem = this.untreatedListItem.concat(data.rows);
}else{
this.dealListItem = this.dealListItem.concat(data.rows);
}
//加载状态处理
if( this.tabIndex == 0 ){//全部
this.status = data.rows.length == this.pageSize ? 'more' : 'noMore';
}else if( this.tabIndex == 1){//未处理
this.untreatedStatus = data.rows.length == this.pageSize ? 'more' : 'noMore';
}else{
this.dealStatus = data.rows.length == this.pageSize ? 'more' : 'noMore';
}
}else{
if( this.tabIndex == 0 ){
this.status = 'noData';
}else if( this.tabIndex == 1){
this.untreatedStatus = 'noData'; //未处理
}else{
this.dealStatus = 'noData'; //已处理
}
}
}else{//接口调取失败
uni.showToast({
icon:'error',
title: data.msg
});
}
},
})
},
/*tab切换*/
tabChange(i) {
this.tabIndex = i;
},
//swiper滑动切换
swiperTab(e) {
this.tabIndex = e.target.current;
if( this.tabIndex == 0 && this.listItem.length==0 ){
this.getList(this.pageNum);
}
if( this.tabIndex == 1 && this.untreatedListItem.length==0 ){
this.getList(this.untreatedPageNum,0);
}
if( this.tabIndex == 2 && this.dealListItem.length==0 ){
this.getList(this.dealPageNum,1);
}
},
}
}
</script>
<style lang="scss" scoped>
.tab-titBar{border-bottom: 1px solid #eff4f9;}
.swiper scroll-view{ height:100%;}
/*列表*/
.list-bar {
padding: 0rpx 32rpx;
padding-top: calc(var(--status-bar-height) + 188rpx);
}
.list-con {
background: #fff;
padding: 24rpx;
margin-bottom: 28rpx;
position:relative;
}
</style>