Uni-app在scroll-view中实现分页加载数据

业务场景:

在scroller-view中显示数据,分页加载数据,当屏幕滑动到当页的最下面的时候分页加载数据,每次将数据追加渲染。

实现效果:

在这里插入图片描述

代码

主页

通过引入自定义组件、实现显示子页面

几个参数:@loadMoreData="getNewList()"监听子组件的分页请求、:loading="hasMore"判断是否还有数据、:dataList="dataList"向子组件传递请求结果

<template>
	
	<view style="width: 100%;height: 100%;">
		<view style="width: 100%;height: 30px;"></view>
		<view class="header center" style="height: 50px;"  >
			<span class="headerFont">点评</span>
		</view>
		<view class="tbar" style="height: 50px;" >
			<view class="tbarPage" @click="changePage(1)" :class="[showPage === 1?'selected':'normal']">
				<span>商铺推荐</span>
			</view>
			<view class="tbarPage" @click="changePage(2)" :class="[showPage === 2?'selected':'normal']">
				<span>美食推荐</span>
			</view>
		</view>
        <!-- calc(100%-130px)计算并固定剩余组件高度 -->
		<index-page1 @loadMoreData="getNewList()" :loading="hasMore" :dataList="dataList" style="width: 100%;height: calc(100% - 130px);" v-show="showPage === 1"></index-page1>
		<index-page2 style="height: calc(100% - 130px);" v-show="showPage === 2"></index-page2>
		
		
	</view>
</template>

<script>
	import indexPage1 from '../../components/index/indexPage1.vue';
	import indexPage2 from '../../components/index/indexPage2.vue';
	export default {
		data() {
			return {
				currentPage: 0,// 当前分页起点
				pageSize: 20,// 分页大小
				showPage: 1, //默认显示页面1
				dataList: [],
				len: 0,
				hasMore: true
			}
		},
		components: {
			indexPage1,indexPage2
		},
		mounted() {
			this.getList()
		}
		,
		methods: {
			changePage(page){
				this.showPage = page//将响应参数传回,从而选择page
			},
            // 向后端发送请求
			getList(){
				uni.request({
				  url: 'http://localhost:8080/shop/getShop',
				  method: 'POST',
				  data: {
				   iCurrentPage: this.currentPage,
				   iPageSize: this.pageSize
				  },
				  success: (res)=> {
				    
					this.dataList = res.data
					this.len = res.data.length
					
					
				  },
				  fail: function(res) {
				    console.log('请求失败', res);
				  }
				});
					
			},
            // 请求新数据
			getNewList(){
				this.currentPage = this.pageSize + this.currentPage
				console.log(this.len)
                // 请求结果数据的条数小于页面大小,表示后面没有数据了
				if(this.len < this.pageSize){
					this.hasMore = false
					console.log("没有更多数据")
				}
				
				this.getList()
				
			}
		}
	}
</script>

<style>
	.header{
		width: 100%;
		height: 50px;
	}
	.headerFont{
		font-size: x-large;
		font-weight: bold;
	}
	.tbar{
		width: 100%;
		height: 50px;
		display: flex;
		background-color: white;
	}
	.tbarPage{
		width: 50%;
		align-items: center;
		justify-content: center;
		display: flex;
	}
	.selected{
		background-color: skyblue;
	}
	.container {
		padding: 20px;
		font-size: 14px;
		line-height: 24px;
	}
	.center {
		align-items: center;
		display: flex;
		justify-content: center;
	}
</style>

数据显示子页面

在scroll-view中设置@scrollertolower监听是否滑动到当页的底部,并且在滑动到底部时调用getNewData方法,通过this.$emit(‘loadMoreData’);向父组件发送请求新页面消息

<template>
	<view style="width: 100%;height: 100%;" class="center">
		<scroll-view scroll-y="true" style="width: 90%;height: 100%;"  @scrolltolower="getNewsData()">
			<view v-for="item in showData" style="height: 100px;width: 100%;
            background-color: whitesmoke;border: 1px darkgray solid;border-radius: 10px;
            margin-top: 10px;">
				<view style="width: 100%;height: 100%;">
					<view style="width: 100 %;height: 70%;"  class="center">
						<span style="font-size: x-large;">{{item.sshopName}}</span>
					</view>
					<view style="width: 90%;height: 30%;display: flex;">
						<view style="width: 100%;height: 100%;" class="center">
							<span>{{item.sshopAddress}}</span>
						</view>
						<view style="width: 100%;height: 100%;" class="center">
							<span>{{item.sshopPhone}}</span>
						</view>
					</view>
				</view>
                <!-- 加载中组件-->
				<uni-load-more :status="loading ? 'loading' : 'nomore'" />
		</scroll-view>
		
	</view>
</template>

<script>
	export default {
		data() {
			return {
				
				showData: [],
				
			}
		},
        // 保存父页面 :dataList、:loading发送的数据
		props:{
			dataList:{
				type: Array,
				default: () => []
			},
			loading:{
				type: Boolean,
				default: true
			}
		},
        // 监听父组件发送的数据
		watch:{
		dataList:function(newVal, oldVal){
				// this.addDataToShow(newVal)
				this.addDataToShow(newVal)
			
			}
		},
		mounted() {
			
		},
		
		methods: {
			// 触发到底请求新数据的方法
			getNewsData () {
				this.$emit('loadMoreData');
				console.log('上拉刷新更多数据')
			},
            // 将新请求的数据追加到渲染数据中
			addDataToShow(data){
				var len = data.length
				
				for(var i = 0;i < len;i++){
					this.showData.push(data[i])
				}
				
				
			}
			
			
		}	
			
			
}
</script>

<style>
	.center {
		align-items: center;
		display: flex;
		justify-content: center;
	}
</style>

其他设置

在app.vue中添加样式

uni-page-body,html,body{
		width: 100%;
	    height: 100%;
	}

在pages.json中设置不可页面滑动(只允许scroller-view滑动)

"path": "pages/sales/Homepage",
		"style": {
			"navigationBarTextStyle": "black",
			"navigationBarTitleText": "home-page",
			"disableScroll": true
			
		}
    height: 100%;
}
在pages.json中设置不可页面滑动(只允许scroller-view滑动)
```json
"path": "pages/sales/Homepage",
		"style": {
			"navigationBarTextStyle": "black",
			"navigationBarTitleText": "home-page",
			"disableScroll": true
			
		}
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐