記錄完了未封裝組件的,這個就拆分一下了,用的時候也比較方便。
components/LoadMore.vue
<template> <div class="my-scroll" @scroll.passive="onScroll($event)" @touchstart="touchStart($event)" @touchmove="touchMove($event)" @touchend="touchEnd($event)" ref="myScroll" :style="'margin-top: '+ scrollMarginTop +'px;height: calc(100vh - ' + scrollMarginTop + 'px);'"> <div class="scroll-top" :style="'height:'+top+'px;'"> <div v-if="aspect==2"> <p v-if="state==6">下拉刷新</p> <p v-if="state==2">松開刷新</p> <p v-if="state==1"> <img :src="Load"/>刷新中 </p> <p v-if="state==3"> <img :src="Load"/>刷新完成 </p> </div> </div> <div class="scroll-list"> <slot name='scrollList'></slot> <!-- <div> <ul> <li v-for="(x,index) in list" :key="index">列表</li> </ul> </div> --> <div class="scroll-bottom"> <p v-if="state==4"><img :src="Load"/>加載中</p> <p v-if="state==5"><img :src="Load"/>加載完成</p> <p v-if="state==7" class="no-more-data" v-show="noMoreState">沒有更多了,我是有底線的</p> </div> </div> </div> </template> <script> import Load from '@/assets/loading1.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 }, 'noMoreState':{//沒有更多是否顯示 type:Boolean, require:true }, 'scrollMarginTop':{ type:Number, default: 100 } }, data(){ return { Load, pageX:0, pageY:0, state:0, scrollPosition:0, myScroll:null, myScrollList:null, top:0, aspect:0, //1:向下 2:向上 listHeight:0, } }, mounted(){ this.myScroll = this.$refs.myScroll //獲取滑條dom this.myScrollList = this.myScroll.children[1] //獲取列表dom }, 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 this.top = 0 },500) } }, touchStart(e){ //觸摸事件 // console.log('觸摸事件',e) this.pageX = e.targetTouches[0].pageX this.pageY = e.targetTouches[0].pageY }, touchMove(e){ //觸摸滑動事件 this.scrollPosition = this.myScroll.scrollTop //獲取滾動條位置 // console.log(this.scrollPosition) 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){ //返回X,Y this.getScrollTop(e.target.scrollTop) } }, topCallback(){ //刷新回調 this.onRefresh(this.state) }, bottomCallback(){ //加載回調 if(this.state != 7){ this.state = 4 this.onPull(this.state) } }, } } </script> <style lang="scss" scoped> .my-scroll{ margin-top: 100px; height: calc(100vh - 100px); background: #fff; overflow: auto; } .scroll-top, .scroll-bottom{ background: #f4f4f4; font-size: 28px; text-align: center; color: #999; p{ padding: 20px 0; } img{ width: 40px; vertical-align: -10px; margin-right: 20px; } } .no-more-data{ position: relative; } .no-more-data::before,.no-more-data::after{ content: ''; position: absolute; top: 50%; transform: translateY(-50%); width: 100px; height: 2px; background: #ccc; } .no-more-data::before{ left: 70px; } .no-more-data::after{ right: 70px; } </style>
使用
<template> <div> <div class="header"> 23213123123131321 </div> <my-scroll ref="myScroll" :page="page" :on-refresh="onRefresh" :on-pull="onPull" :get-scroll-top="getTop" :scrollState="scrollState" :noMoreState="noMoreState"> <div slot="scrollList"> <ul> <li v-for="(x,index) in list" :key="index">{{index}}</li> </ul> </div> </my-scroll> </div> </template> <script> import myScroll from '@/components/LoadMore.vue' export default { components:{ myScroll }, data(){ return{ page:{ counter:1, pageStart:1, pageEnd:1, total:1 }, scrollState:true, noMoreState:false, list:[] } }, mounted(){ for(let i=0;i<1*20;i++){ this.list.push({}) } }, methods: { onRefresh(mun){ //刷新回調 console.log(mun) setTimeout(()=>{ this.$refs.myScroll.setState(3) // 下拉刷新數據重新請求 if(mun === 1){ this.page.counter = 1; this.list = []; for(let i=0;i<20;i++){ this.list.push({}) } } },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.list.push({}) } },500) }else{ if(this.page.counter !== 1){ this.noMoreState = true } this.$refs.myScroll.setState(7); } }, getTop(y) {//滾動條位置 }, } } </script> <style lang="scss" scoped> .header{ position: fixed; top: 0; left: 0; right: 0; height: 100px; z-index: 102; background: #666; } li{ font-size: 28px; color: #666; border-bottom: 1px solid #eee; margin-left: 20px; padding: 20px 0; } </style>
也是需要整個loading圖,然后直接用就可以了