vue移动端上拉加载更多

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>

猜你喜欢

转载自www.cnblogs.com/yhquan/p/10594459.html
今日推荐