vue實現分頁 上拉加載下拉刷新——組件版


 

  記錄完了未封裝組件的,這個就拆分一下了,用的時候也比較方便。

  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圖,然后直接用就可以了

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM