封装组件:
<template>
<view class="zcPagination">
<zc-u-toast></zc-u-toast>
<slot v-if="!loading && !list.length" name="emptyState"/>
<slot/>
<view class="loadState">
<view v-if="loading" class="loading">
<u-loading-icon text="加载中" color="#ccc" textColor="#ccc" size="13" textSize="13"></u-loading-icon>
</view>
<view v-else-if="nomore" class="nomore">
<view class="spacer"></view>
<u--image width="18px" height="17px" src="/static/nomore.svg"></u--image>
<text style="color: #ccc;font-size: 13px;">到底啦!</text>
<view class="spacer"></view>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
option: {
type: Object,
default: () => ({})
},
list: Array,
getRemoteList: Function
},
data() {
return {
pageSize: this.option.pageSize,
pageNo: this.option.pageNo,
loading: false,
nomore: false
}
},
methods: {
async refresh() {
if(!this.list.length) return
const pageSize = this.list.length
const pageNo = 1
this.loading = true
const res = await this.getRemoteList.call(this.$parent, { pageSize, pageNo })
this.loading = false
if(res.status) {
const list = res.data
this.$emit('update:list', list)
if(res.total === list.length) this.nomore = true
else this.nomore = false
}else{
this.$store.commit('uToast', { type: 'error', message: res.msg })
}
},
async load() {
const { pageSize, pageNo } = this
this.loading = true
const res = await this.getRemoteList.call(this.$parent, { pageSize, pageNo })
this.loading = false
if(res.status) {
this.pageNo++
const list = this.list.concat(res.data)
this.$emit('update:list', list)
if(res.total === list.length) this.nomore = true
else this.nomore = false
}else{
this.$store.commit('uToast', { type: 'error', message: res.msg })
}
}
}
}
</script>
<style lang="scss" scoped>
.zcPagination{
.loadState{
padding: 8px;
.nomore{
display: flex;
justify-content: center;
position: relative;
.spacer{
width: 60px;
height: 2px;
transform: translateY(8px);
margin: 0 10px;
background: linear-gradient(282deg, #CCCCCC 0%, transparent 100%);
&:last-of-type{
background: linear-gradient(282deg, transparent 0%, #CCCCCC 100%);
}
}
text{
margin-left: 10rpx;
}
}
}
}
</style>
使用组件:
<template>
<view>
<zc-pagination ref="zcPagination" :option="{pageSize, pageNo}" :list.sync="list" :getRemoteList="getRemoteList">
<zc-jobs v-for="(item, index) of list" :key="index" :item="item" :index="index"/>
<zc-empty slot="emptyState"/>
</zc-pagination>
</view>
</template>
<script>
export default {
data() {
return {
pageSize: 14,
pageNo: 1,
list: []
}
},
onShow() {
// 刷新数据
this.$refs['zcPagination'] && this.$refs['zcPagination'].refresh()
},
onReady() {
this.$refs['zcPagination'].load()
},
onReachBottom() {
this.$refs['zcPagination'].load()
},
methods: {
getRemoteList({ pageSize, pageNo }) {
const params = {
title: '精装修',
pageNo,
pageSize
}
return this.$store.dispatch('user/findJob', params)
}
}
}
</script>
这里是以uniapp+uview为例提供一个实现方式和思路,大家根据实际项目情况改动,如果是纯H5使用其他list组件(如:vant-list、better-scroll等)可以判断触底事件的组件替代onReachBottom。
另外打个广告,最近发现了一个很好用的扶墙工具,支持多种方案,很便宜很稳定:速蛙云