LoadMore.vue
<template> <div class="load-more-wrapper" @touchstart="touchStart($event)" @touchend="touchEnd($event)"> <div class="inner"> <slot></slot> <div class="load-more" v-show="enableLoadMore">{{loadMoreText}}</div> <div class="load-end" v-show="!enableLoadMore">已经到底了!</div> </div> </div> </template>
<script> export default { name: "LoadMore", props: { enableLoadMore: { type: Boolean, default: true }, onLoadMore: { type: Function, default: undefined, require: false } }, data() { return { loadMoreText: "上拉加载更多", startX: 0, startY: 0, isLoading: false, } }, methods: { touchStart(e) { this.startY = e.targetTouches[0].pageY; this.startX = e.targetTouches[0].pageX; }, scrollToEnd(e) { let scrollHeight = this.$el.scrollHeight; let clientHeight = this.$el.clientHeight; let scrollTop = this.$el.scrollTop; if (scrollTop + clientHeight >= scrollHeight || this.enableLoadMore) { this.doLoadMore() } }, touchEnd(e) { if (this.isLoading) { return; } let endX = e.changedTouches[0].pageX, endY = e.changedTouches[0].pageY, dy = this.startY - endY, dx = endX - this.startX; if(Math.abs(dx) < 2 && Math.abs(dy) < 2) { return; } if (endY < this.startY) { this.scrollToEnd(e) } }, doLoadMore() { this.isLoading = true this.loadMoreText = '加载中...' this.onLoadMore(this.loadDone); }, loadDone() { this.isLoading = false; this.loadMoreText = '上拉加载更多' } } } </script>
<style lang="scss" scoped> .load-more-wrapper { height: 100%; overflow-y: auto; -webkit-overflow-scrolling: touch; transition-duration: 300ms; .load-more, .load-end { color: #aea699; font-size: .26rem; margin: .3rem 0; text-align: center; } } </style>
使用如下:
Main.vue
<template> <div class="main-page-wrapper"> <LoadMore :onLoadMore="onLoadMore" :enableLoadMore="enableLoadMore"> <ListItem :listData="listData"></ListItem> </LoadMore> </div> </template>
<script> import ListItem from './ListItem' import LoadMore from './LoadMore'; import { getListData } from '../js/service.js' export default { name: "MainPage", components: { ListItem, LoadMore }, data() { return { listData: [], page: 0, enableLoadMore: true, } }, methods: { onLoadMore(done) { setTimeout(()=>{ if(!this.enableLoadMore) { return } this.page = this.page + 1 this.getListData(); done(); }, 200) }, getListData() { let reqData = { reqData: "接口请求字段" } getListData(reqData).then((res)=> { if(res.length < 20) { this.enableLoadMore = false } this.listData = this.listData.concat(res); }) } } } </script>
<style lang="scss" scope> .main-page-wrapper { position: relative; display: flex; height: 100%; -webkit-box-orient: vertical; flex-direction: column; } </style>