uni-app使用swiper实现tab左右滑动下拉无法触发onReachBottom页面生命周期

注意要点

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>

上一篇:vue 单独封装分页组件


下一篇:mixin table 表格封装查询 重置 分页