vue 移动端实现上滑下拉分页加载数据小demo

<template>

    <div class="my-scroll" :class="[scrollState?'prohibit':'allow']" ref="myScroll" @scroll.passive="onScroll($event)" @touchstart="touchStart($event)" @touchmove="touchMove($event)" @touchend="touchEnd($event)"  >

        <div class="scroll-top" :style="{height:top+'px'}">

            <div v-if="aspect==2">

                <p v-if="state==6">

                    下拉刷新

                </p>

                <p v-if="state==1">

                    <i><img :src="Load"/></i>

                    <br/>

                    刷新中

                </p>

                <p v-if="state==2">松开刷新</p>

                <p v-if="state==3">

                    <i><img :src="Load"/></i>

                    <br/>

                    刷新完成

                </p>

            </div>

        </div>

        <!-- top -->

        <div class="scroll-list" :style="{ transform: 'translate3d(0, ' + top + 'px, 0)'}">

            <slot name='scrollList'></slot>

            <div class="scroll-bottom">

                <div v-if="state==4">加载中</div>

                <div v-if="state==5">加载完成</div>

                <div v-if="state==7">没有更多</div>

            </div>

        </div>

    </div>

</template>

<script type="text/javascript">

import tween from '@/plugins/tween'

import Load from '@/assets/Load.gif'

    export default {

        name:'myScroll',

        props:{

            'page':{

                type:Object,  //counter:当前页  pageStart:开始页数  pageEnd:结束页数  total:总页数

            },

            'onRefresh':{ //刷新回调

                type:Function,

                require:true

            },

            'onPull':{ //加载回调

                type:Function,

                require:true

            },

            'getScrollTop':{ //获取滚动条位置

                type:Function

            },

            'setScrollPage':{ //改变滚动条位置

                type:Function

            },

            'scrollState':{//是否可滑动

                type:Boolean,

                require:true

            }

        },

        data(){

            return {

                Load,

                pageX:0,

                pageY:0,

                state:0,

                scrollPosition:0,

                myScroll:null,

                myScrollList:null,

                top:0,

                aspect:0, //1:向下 2:向上

                listHeight:0,

            }

        },

        created(){

        },

        methods:{

            ScrollTop(top){ //修改滚动条位置

                this.myScroll.scrollTop = top

            },

            /*

            * 刷新中:1

            * 松开刷新:2

            * 刷新完成:3

            * 加载中:4

            * 加载完成:5

            * 下拉刷新:6

            * 没有更多:7

            */

            setState(index){ //修改状态

                this.state = index

                if(index == 5||index == 3){

                    setTimeout(()=>{

                        this.state = 0

                        let timer = null;

                        let that = this;

                        var b=50,c=100,d=100,t=0;

                        cancelAnimationFrame(timer);

                        timer = requestAnimationFrame(function fn() {

                            var oTop = that.top;

                            if (that.top>0) {

                                that.top = Math.ceil(tween.Quart.easeInOut(10,oTop,8,10)) - 15

                                timer = requestAnimationFrame(fn);

                            } else {

                                cancelAnimationFrame(timer);

                                that.top = 0

                            }

                        });

                    },500)

                }

            },

            touchStart(e){ //触摸事件

                this.pageX = e.targetTouches[0].pageX

                this.pageY = e.targetTouches[0].pageY

            },

            touchMove(e){ //触摸滑动事件

                this.scrollPosition = this.myScroll.scrollTop //获取滚动条位置

                if(this.scrollState&&e.targetTouches[0].pageY>this.pageY){ //向上滑动

                    this.aspect = 2

                    if(this.myScroll.scrollTop==0){

                        let diff = e.targetTouches[0].pageY - this.pageY - this.scrollPosition

                        this.top = Math.pow(diff, 0.9)

                        let ranget = diff/document.body.clientHeight*100 //计算在屏幕上滑动了多少

                        if(ranget > 20){

                            this.state = 2

                        }else if(ranget < 15){

                            this.state = 6

                        }

                        e.preventDefault()

                    }

                }else if(this.scrollState&&this.state!=4){ //向上滑动

                    this.aspect = 1

                }

            },

            touchEnd(e){

                if(this.aspect == 2&&this.state == 2||this.state == 1){ //上拉处理

                    this.top = 100

                    this.state = 1

                    this.topCallback()

                }else if(this.aspect == 2){

                    this.state = 0

                    this.top = 0

                }

            },

            onScroll(e){

                let listHeight = this.myScrollList.offsetHeight //列表总高度

                let listScrollTop = e.target.scrollTop + this.myScroll.offsetHeight //当前滚动条位置

                if(this.state == 0&&listHeight-listScrollTop < 100){

                    this.bottomCallback()

                }

                if(this.getScrollTop)this.getScrollTop(e.target.scrollTop) //返回X,Y

            },

            topCallback(){ //刷新回调

                this.onRefresh(this.state)

            },

            bottomCallback(){ //加载回调

                if(this.state != 7){

                    this.state = 4

                    this.onPull(this.state)

                }

            },

        },

        mounted(){

            this.myScroll = this.$refs.myScroll //获取滑条dom

            this.myScrollList = this.myScroll.children[1] //获取列表dom

        }

    }

</script>

<style lang="scss" scoped>

    .allow{

        overflow:hidden;

        height: auto;

    }

    .prohibit{

        max-width: 100%;

        max-height: 100%;

        height: 100%;

        overflow:hidden;

        overflow-y: scroll;

        -webkit-overflow-scrolling: touch;

        will-change: transform;

        transition: all 450ms;

        backface-visibility: hidden;

        perspective: 1000;

    }

    .my-scroll{

        position: relative;

        color: #fff;

        .scroll-top{

            text-align: center;

            display:flex;

            position:absolute;

            top:0;

            left:0;

            width:100%;

            overflow: hidden;

            div{

                display:flex;

                height:auto;

                width:100%;

                justify-content: center;

                align-items:center;

                flex-wrap: wrap;

                i{

                    flex:1 0 100%;

                    display:block;

                    height: 0.4rem;

                }

                img{

                    width:0.6rem;

                }

                p{

                    flex:1 0 100%;

                }

            }

        }

        .scroll-list{

            overflow:hidden;

            min-height: 100%;

        }

        .scroll-bottom{

            text-align: center;

            line-height: 40px;

        }

    }

</style>

用法:

<template>

    <div class="index">

        <my-scroll  ref="myScroll" :page="page" :on-refresh="onRefresh" :on-pull="onPull"  :get-scroll-top="getTop">

        <div slot="scrollList">

            <ul>

                <li v-for="(x,index) in list" :key="index">列表</li>

            </ul>

        </div>

        </my-scroll>

    </div>

</template>

<script type="text/javascript">

    import myScroll from '@/components/myScroll.vue'

    export default {

        data(){

            return{

                list:[],

                page:{

                    counter:1, 

                    pageStart:1, 

                    pageEnd:1, 

                    total:10

                },

            }

        },

        methods:{

            onRefresh(mun){ //刷新回调

                    setTimeout(()=>{

                        this.$refs.myScroll.setState(3);

                    },500)

            },

            onPull(mun){ //加载回调

                if(this.page.counter<=this.page.total){

                    setTimeout(()=>{

                        this.page.counter++

                        this.$refs.myScroll.setState(5)

                        for(let i=0;i<10;i++){

                            this.listdata.push({})

                        }

                    },500)

                }else{

                    this.$refs.myScroll.setState(7)

                }

            },

            getTop(y) {//滚动条位置

            },

        },

        components:{

            myScroll

        },

        created(){

        },

        mounted(){

            for(let i=0;i<1*50;i++){

                this.list.push({})

            }

        },

    }

</script>

<style lang="scss" scoped>

    .index{

    }

</style>

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容