适用于一个页面加载不完所有的数据,,需要分页去向后台请求数据的情景
主要的tips有以下三点
1 要监听滚轮事件,当滚轮距离底部一段距离H时,开始去请求数据
2 当在去请求数据的时候,这时就要禁止滚轮再次滚动,如果不禁止,就会出现一直会出现距离H的情况,这时候就会回到第一步骤再去重新,反复的从后台请求数据
3 定义一个滚动事件,默认为loadMore(),代表在距离为H时要触发的方法,一般内部就是请求数据的操作
以下就是选择的vue-infinite-scroll插件进行更详细的说明
npm i vue-infinite-scroll -S
在main.js里
import infiniteScroll from 'vue-infinite-scroll'
Vue.use(infiniteScroll)
<div class="content clearfix">
<ul class="clearfix">
<li class="gl-list-con" v-for="item in goodsList">
<h3>{{item.productName}}</h3>
</li>
</ul>
<!--v-infinite-scroll-->
<div v-infinite-scroll="loadMore" infinite-scroll-disabled="busy" infinite-scroll-distance="30">
.....加载中
</div>
</div>
v-infinite-scroll是放在列表的下方,,当页面进来的时候,,列表会先请求后台返回的page1的数据,然后当H为30时,触发loadMore方法,这里的busy代表是否禁用滚动事件,true代表禁用,false代表打开滚动权限。初始状态下设置为true,所以我们每次在触发loadMore方法的时候。一定要禁用滚动事件,简单的理解就是不要让屏幕再次出现有距离H的情况,然后再请求完数据的时候,,先检查一下是否还会有多余的数据,如果有的话,busy值设置为false,让屏幕再次滚动,再次触发函数,如果没有的话,就直接禁止滚动。
data () {
return {
// scroll
busy: true, //
},
methods: {
// 当属性滚动的时候 加载 滚动加载
loadMore () {
this.busy = true // 将无限滚动给禁用
this.page++ // 增加页数
this.searchSource() // 请求数据
},
searchSource () {
api
.post('/api/house/common/list', this.searchHouse)
.then(result => {
let listTotal = result.data.total
if (当没有多余的数据时) {
this.scrollDisabled = true // 将无限滚动关闭
this.page = 0 // 页数变为0
} else {
this.scrollDisabled = false // 当还有多余的数据时,将无限滚动给打开 ,就是可以继续滚动去请求后台
}
})
.catch(res => {
this.$message.error('获取失败')
})
},
优化的地方在于,可以在loadMore的事件里加一个定时器,如果用户一直往下滑就会很快的一直去后台请求,页面就会很快的去更新,我们可以让每次触发函数的时候,间隔500毫秒,每当满足H时,500毫秒后再去请求数据,用户的体验会更好。
loadMore(){
this.busy=true //将无限滚动给禁用
setTimeout(() => { //发送请求有时间间隔第一个滚动时间结束后才发送第二个请求
this.page++; //滚动之后加载第二页
this.searchSource();
}, 500);
接下来的最后一关就是解决以下三种情况的页面展示问题
当没有第一页数据的时候
当有第一页数据的时候
1,显示正在加载的
2 ,显示没有更多数据
先看代码
<el-row :gutter="20" v-show="contentShow">
<el-col :span="8" v-for="(item, index) in houseList" :key="index">
<div class="textCover">
<p><span>{{item.communityName}}</span></p>
<p>{{item.originLayout}} | 建筑面积{{item.floorArea}}㎡</p>
</div>
</div>
<div>
</div>
</el-col>
</el-row>
<el-row v-if="!contentShow">
<p class="empty">暂时没找到相应的房源</p>
</el-row>
<!-- scroll -->
<div v-show="contentShow" v-infinite-scroll="loadMore" infinite-scroll-disabled="scrollDisabled" infinite-scroll-distance="10">
<div>
<p v-show="infiniteMsgShow" class="tips">加载更多ing</p>
<p v-show="!infiniteMsgShow" class="tips"> 没有更多数据</p>
</div>
</div>
<!-- scroll -->
我定义了contenshow的变量,旨在确定根据返回的数据渲染页面的两种情况,在data中定义true。
searchSource () {
api
.post('/api/house/common/list', this.searchHouse)
.then(result => {
let listTotal = result.data.total
if (listTotal > 0) {
this.contentShow = true
} else {
this.contentShow = false
}
this.loading = false
this.houseList = this.houseList.concat(result.data.houses)
let DownloadTotal =
(this.searchHouse.page + 1) * this.searchHouse.size
let total = result.data.total
this.houseNum = result.data.total
// this.searchHouse.page++; //增加页数
if (DownloadTotal >= total) {
this.scrollDisabled = true // 将无限滚动关闭
this.searchHouse.page = 0 // 页数变为0
this.infiniteMsgShow = false // 切换底部提示信息
} else {
this.scrollDisabled = false // 将无限滚动给打开
this.infiniteMsgShow = true
}
})
.catch(res => {
this.$message.error('获取失败')
this.contentShow = false
})
},
在请求中动态确定contenshow值
当有第一页内容时,scroll的dom节点也同为true,即contenshow为true
定义一个infiniteMsgShow,分别渲染在没有更多数据和正在加载数据这个两种情况
当没有第一页数据时,显示
暂时没找到相应的房源