vue在移動端開發過程當中,上拉加載、下拉刷新是頁面的基本需求,如今給你們介紹一種基於touch事件封裝的刷新組件。html
組件支持傳參、傳遞事件、請求成功異步回調、上拉與觸底觸發加載或刷新。vue
這裏咱們有兩個頁面,父組件note.vue與刷新組件baseScroll.vue。ajax
經過Prop向子組件傳遞數據、經過事件向父組件發送消息、經過插槽slot分發內容。json
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:this
props:{ // 請求數據的地址 url:'', // 請求參數 param:{ type: Object, }, // 每頁顯示數據條數 pageSize: { default:10 }, pageNoName: { default: 'page_no' }, pageSizeName: { default: 'page_size' }, }
組件裏面咱們使用touch相關事件來達到刷新、加載的效果。url
baseScroll:spa
<div class="vue-scroll" @touchstart="touchStart($event)" @touchmove="touchMove($event)" @touchend="touchEnd($event)"> <slot name="content"></slot> </div>
其實機制很簡單,就是上滑到頁面頂部觸發刷新,滑動到頁面觸底觸發數據加載 。關鍵咱們要經過偏移量來判斷何時刷新或加載。這裏有篇詳細介紹頁面偏移量的文章,點我傳送門!
code
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)傳遞數據給父組件,固然頁面數據上的操做顯示就交給父組件進行模板渲染,子組件內部能夠作些加載、刷新的動畫顯示。
而且只要涉及到頁面分頁、須要上拉下拉操做的頁面均可以複用該組件,只是接口地址、參數不一樣!