1. 程式人生 > >vue-上拉載入、下拉重新整理元件

vue-上拉載入、下拉重新整理元件

vue在移動端開發過程中,上拉載入、下拉重新整理是頁面的基本需求,現在給大家介紹一種基於touch事件封裝的重新整理元件。

元件支援傳參、傳遞事件、請求成功非同步回撥、上拉與觸底觸發載入或重新整理。

父子元件間的通訊

這裡我們有兩個頁面,父元件note.vue與重新整理元件baseScroll.vue。

通過Prop向子元件傳遞資料、通過事件向父元件傳送訊息、通過插槽slot分發內容。

note:

<base-scroll v-bind:url="url" 
             v-bind:param="param" 
             @send-data="sendData" 
             ref
="baseScroll">
  <div slot="content">
    <!--內容區-->
  </div>
</base-scroll>

這裡我們note頁面向子元件傳遞了請求地址、引數,sendData則用來接收子元件的事件回撥。

baseScroll:

props:{
        // 請求資料的地址
        url:'',
        // 請求引數
        param:{
            type: Object,
        },
        // 每頁顯示資料條數
        pageSize: {
            
default:10 }, pageNoName: { default: 'page_no' }, pageSizeName: { default: 'page_size' }, }

下拉重新整理、上拉載入觸發條件

元件裡面我們使用touch相關事件來達到重新整理、載入的效果。

baseScroll:

<div class="vue-scroll"
    @touchstart="touchStart($event)"
    @touchmove
="touchMove($event)" @touchend="touchEnd($event)"> <slot name="content"></slot> </div>

其實機制很簡單,就是上滑到頁面頂部觸發重新整理,滑動到頁面觸底觸發資料載入 。關鍵我們要通過偏移量來判斷什麼時候重新整理或載入。這裡有篇詳細介紹頁面偏移量的文章,點我傳送門

baseScroll:

touchStart(e) {  
    // 螢幕高度
    this.clientHeight=parseInt(`${document.documentElement.clientHeight}`) 
    //滾動開始頁面距頂距離
    this.scrollTopStart=window.scrollY    
    // 頁面高度                 
    this.pageHeight=e.currentTarget.clientHeight
    // 觸控距離頁面起點
    this.startY = e.targetTouches[0].pageY 
    // 觸控距離螢幕起點 
    this.clientY = e.targetTouches[0].clientY
},
touchEnd(e) {
    if(!this.hasMove)return
    this.hasMove=false
    // 滾動結束頁面距頂距離
    this.scrollTopEnd=window.scrollY 
    var sLength=this.scrollTopEnd-this.scrollTopStart
    if(this.clientHeight+this.startY+sLength+15>=this.pageHeight+this.clientY){
        this.nextPage()  //頁面載入
    }else if(this.startY+sLength<=this.clientY){
        this.refresh()  //頁面重新整理
    }     
},
touchMove(e) {
    this.hasMove=true
},
touchStart拿到滾動起點的位置及其他頁面或螢幕高度;touchEnd中通過判斷滾動的值來確定是載入或重新整理;hasMove值用來區分使用者的操作是點選還是滑動。

載入資料、執行回撥

確認後是下拉重新整理還是上拉載入後,我們執行相應的操作。

baseScroll:

refresh(){
    this.currPageNo = 1
    this.getData(data=>{
       
    },0)
},
nextPage(){
    this.getData(data => {
    }, 1)
},
getData(callback, type){
    var self=this
    // 設定分頁引數
    if (typeof this.param === 'string') {
      this.param = JSON.parse(this.param);
    }
    this.param[this.pageNoName]=this.currPageNo
    this.param[this.pageSizeName]=this.pageSize
    $.ajax({
        type: "get",
        url: this.url,
        data: this.param,
        dataType: 'json',
        success: function (res) {
            var data=res.data
            callback(data)
            self.currPageNo += 1;     
            self.$emit('send-data', data,type)            
        },
    })
},

這裡我是呼叫介面獲取資料然後$emit('send-data',data,type)傳遞資料給父元件,當然頁面資料上的操作顯示就交給父元件進行模板渲染,子元件內部可以做些載入、重新整理的動畫顯示。

並且只要涉及到頁面分頁、需要上拉下拉操作的頁面都可以複用該元件,只是介面地址、引數不同!