vue-上拉載入、下拉重新整理元件
阿新 • • 發佈:2018-12-03
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)傳遞資料給父元件,當然頁面資料上的操作顯示就交給父元件進行模板渲染,子元件內部可以做些載入、重新整理的動畫顯示。
並且只要涉及到頁面分頁、需要上拉下拉操作的頁面都可以複用該元件,只是介面地址、引數不同!