vue - 下拉加载更多

上拉刷新下拉加载更多

vue好多插件可以使用,完成该功能,但是我使用过几个插件之后,不知道是不是自己没有找对方法,都没有解决我得问题

我出现得情况是,下拉时请求下一页得数据,但是如果数据条数过多,比如一页请求10条数据,屏幕太短只能显示5条数据,那么再次下拉就不是请求数据,而是想看下面内容~不知道怎么识别是下拉请求数据啊,还是想看下面的数据~

前两天发现自己很傻缺,不使用下拉请求数据,直接到最底部再请求数据就好了啊。。。。然后自己原生写了一个,基本解决了我得问题,只是判断到最底部后请求数据

这两天又研究了一下~出现了下面的代码

代码 myScroll.vue

style样式是自己随便写的,里面注释都有写

<template>
    <div class="yo-scroll" 
        :class="{'down':(state===0),'up':(state==1),refresh:(state===2),touch:touching}" 
        @touchstart="touchStart($event)" @touchmove="touchMove($event)" @touchend="touchEnd($event)">
        <section class="inner" :style="{ transform: 'translate3d(0, ' + top + 'px, 0)' }">
            <header class="pull-refresh">
                <slot name="pull-refresh">
                    <span class="down-tip">下拉更新...</span>
                    <span class="up-tip">松开刷新数据...</span>
                    <span class="refresh-tip">加载中……</span>
                </slot>
            </header>
            <slot>
            </slot>
            <footer class="load-more">
                <slot name="load-more">
                    <span v-show="downFlag === false">上拉加载更多...</span>
                    <!-- <span v-if="loadMoreTip">加载中...</span> -->
                </slot>
            </footer>
            <div class="nullData" v-show="dataList.noFlag">暂无更多数据</div>
        </section>
    </div>
</template>
<script>
    export default{
        naem:'demo',
        props: {
            offset: {
                type: Number,
                default: 100 //默认高度
            },
            enableInfinite: {
                type: Boolean,
                default: true
            },
            enableRefresh: {
                type: Boolean,
                default: true
            },
            dataList: {
                default: false,
                required: false
            },
            onRefresh: {
                type: Function,
                default: undefined,
                required: false
            },
            onInfinite: {
                type: Function,
                default: undefined,
                require: false
            }
        },
        data(){
             return {
                top: 0,
                state: 0,
                startX: 0, //触摸目标在页面中的x坐标
                startY: 0, //触摸目标在页面中的y坐标
                touching: false,
                infiniteLoading: false,
                downFlag: false, //用来显示是否加载
                loadMoreTip:false //数据加载中
            }
        },
        methods:{
            touchStart(e){ //当手指触摸屏幕时触发
                this.startX = e.targetTouches[0].pageX;  
                this.startY = e.targetTouches[0].pageY;
                this.startScroll = this.$el.scrollTop || 0;
                this.touching = true; 
                // this.dataList.noFlag = false; //有更多数据,所以该提示不显示
                this.$el.querySelector('.load-more').style.display = 'block'; //上拉加载更多显示
            },
            touchMove(e){ //当手指在屏幕上滑动的时候连续地触发
                if(!this.enableRefresh || this.dataList.noFlag || !this.touching){
                    return 
                }
                //给下拉做回弹效果
                let diff = e.targetTouches[0].pageY - this.startY - this.startScroll ;
                if(diff > 0) e.preventDefault()
                this.top = Math.pow(diff, 0.8) + (this.state === 2 ? this.offset : 0)
                if(this.state === 2) { // in refreshing
                    return
                }
                if(this.top >= this.offset) {
                    this.state = 1
                } else {
                    this.state = 0
                }
                let more = this.$el.querySelector('.load-more');
                if(!this.top && this.state === 0) {  //没有到顶部
                    more.style.display = 'block';
                } else {
                    more.style.display = 'none';
                }
            },
            touchEnd(e){  //当手指从屏幕上离开的时候触发
                // if(!this.enableRefresh) {
                //     return
                // }
                this.touching = false ;
                if(this.state === 2) { // 在刷新中
                    this.state = 2
                    this.top = this.offset
                    return
                }
                if(this.top >= this.offset) {  //刷新
                    this.refresh()
                } else {                      // 取消刷新
                    this.state = 0
                    this.top = 0
                }
                //用于判断滑动是否在原地 
                // ---------- 开始 --------------
                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) {
                    console.log("滑动距离太短")
                    return;
                }
                // ---------- 结束 --------------

                if(!this.enableInfinite || this.infiniteLoading) {
                    return
                }
                let outerHeight = this.$el.clientHeight,
                    innerHeight = this.$el.querySelector('.inner').clientHeight,
                    scrollTop = this.$el.scrollTop,
                    ptrHeight = this.onRefresh ? this.$el.querySelector('.pull-refresh').clientHeight : 0,
                    bottom = innerHeight - outerHeight - scrollTop - ptrHeight;
                if(bottom <= this.offset && this.state === 0){
                    this.downFlag = true;
                    this.infinite();  //加载
                }else{
                    this.$el.querySelector('.load-more').style.display = 'none';
                    this.downFlag = false;
                }
            },
            refresh(){
                this.state = 2;
                this.top = this.offset;
                setTimeout(() => {
                    this.onRefresh(this.refreshDone)
                }, 1500);
            },
            refreshDone(){
                this.state = 0
                this.top = 0
            },
            infinite() {
                this.state ==  2;
                this.infiniteLoading = true
                setTimeout(() => {
                    // this.loadMoreTip = true ;
                    this.onInfinite(this.infiniteDone);
                }, 1500);
            },
            infiniteDone() {
                this.infiniteLoading = false
            }
        }
    }
</script>
<style scoped> 
    .yo-scroll{
        font-size: 24px;
        position: absolute;
        top: 1rem;
        left: 0;
        bottom:0;
        right:0;
        overflow: auto;
        z-index: 100;
        height: auto;
        -webkit-overflow-scrolling: touch;
    }
    .inner{
        position: absolute;
        /* top:-5rem; */  
        top:0;
        left:0;
        width:100%;
        height:auto;
        transition-duration: 300ms;
    }
    /* 下拉刷新 */
    .pull-refresh{  
        position: relative;
        top:0;
        left:0;
        width:100%;
        height:2rem;
        display:flex;
        display: -webkit-flex;
        justify-content: center;
        align-items: center;
    }
    /* 上拉加载更多 */
    .load-more{  
        width:100%;
        height:2rem;
        line-height:2rem;
        display:flex;
        display: -webkit-flex;
        align-items: center;
        justify-content: center;
        text-align:center;
        display:none;
    }
    /* 没有更多数据 */
    .nullData{
        height:2rem;
        line-height:2rem;
        text-align:center;
    }
    .down-tip,.refresh-tip,.up-tip { /*隐藏提示语*/
        display: none;
    }
    .yo-scroll.touch .inner {
        transition-duration: 0;
    }
    .yo-scroll.down .down-tip {
        display: block;
    }
    .yo-scroll.up .up-tip {
        display: block;
    }
    .yo-scroll.refresh .refresh-tip {
        display: block;
    }
</style>

需要使用上拉加载数据的页面  index.js

<template>
    <div id="scrollList">
         <div class="contSingleList">
            <div class="tabItem">
                <slot></slot>
            </div>
            <v-scroll :on-refresh="onRefresh" :on-infinite="onInfinite" :dataList="scrollData">
                <ul class="listItem">
                    <li v-for="(item,index) in listdata" :key="index">
                        {{item.time}}
                    </li>
                </ul>
            </v-scroll>
        </div>
    </div>
</template>
<script>
    import vScroll from './demo'
    export default{
        name:'scrollList',
        data(){
            return{
                counter: 1, //当前页
                num: 15, // 一页显示多少条
                pageStart: 0, // 开始页数
                pageEnd: 0, // 结束页数
                listdata: [], // 下拉更新数据存放数组
                scrollData: {
                    noFlag: false //暂无更多数据显示
                },
            }
        },
        components: {
            'v-scroll': vScroll
        },
        created(){
            this.getlist();
        },
        methods:{
            getlist(){
                this.$store.dispatch('scroll/getList',this.counter).then(()=>{
                    console.log(this.counter);
                    if(this.$store.state.scroll.code == 200){
                        this.listdata = this.listdata.concat(this.$store.state.scroll.list);
                        if(this.$store.state.scroll.list.length == 0){
                            let more = this.$el.querySelector('.load-more')
                            more.style.display = 'none'; //隐藏加载条
                            //走完数据调用方法
                            this.scrollData.noFlag = true;
                        }
                    }else{
                        this.$toast({ message:this.$store.state.scroll.msg });
                    }
                }).catch((e) => {              
                    //alert(e);
                });
            },
            onRefresh(done) {
                this.listdata = []
                this.counter = 1;
                this.getlist();
                done()
                // this.onInfinite(done)
            },
            onInfinite(done) {
                if(this.scrollData.noFlag){
                    console.log("111")
                }else{
                    this.counter ++;
                    this.getlist();
                    done();
                }
            }		
        }
    }
</script>
<style scoped>
    .listItem{
        width:100%;
    }
    .listItem li{
        width:100%;
        height:2rem;
        border:1px solid red;
        box-sizing: border-box;
        text-align:center;
    }
</style>


js文件请求接口

import axios from 'axios'
export default{
    namespaced:true,
    state:{
        code:0,//状态码
        msg:'',//提示信息
        list:[],//接收数组
    },
    mutations:{
        mtgetcode(state,data){
            state.code = data;
        },
        mtgetmsg(state,data){
            state.msg = data;
        },
        mtgetlist(state,data){
            state.list = data;
        },
    },
    actions:{
        getList:function({commit},info){
            let token = window.localStorage.getItem('date');
            return new Promise((resovle,reject)=>{
                axios.get('url?accessToken='+token+'&page='+info).then((res)=>{
                    const data = res.data;
                    console.log(data);
                    commit('mtgetcode',data.code);
                    commit('mtgetmsg',data.msg);
                    commit('mtgetlist',data.bill);
                    resovle(res);
                }).catch(error => {
                    reject(error);
                })
            })
        }
    }
}

猜你喜欢

转载自blog.csdn.net/Janus_lian/article/details/83900759
今日推荐