uni-app | 上拉載入和下拉重新整理探索

洋小洋同學發表於2020-02-17

Vue 生態 - 多端解決方案 uni-app

個人練手專案《某瓣電影 APP》

列表頁上拉載入更多,下拉重新整理效果

輕鬆實現上拉載入、下拉重新整理、返回頂部

實現效果

demo.gif

前期準備

後端介面

在這個小案例中,我們採用開源的jsonplaceholder,這也是我們前端常用的測試介面。為了達到小 demo 的效果暫且使用這個,後續替換為 douban-api

甚至我們都不用mock介面,同時最重要的一點是支援分頁查詢,查詢的引數是

  • offset
  • limit

寫過後臺的應該對這兩個欄位不陌生,offset偏移量的意思,這個在nest官網也有提到

{
    "page":1,
    "limit":10
}
複製程式碼

在請求的時候類似是這種,傳的頁面的資訊,不過我們輸入的引數

{
    "_offset":xx, // 其中xx 代表的是第幾頁
    "_limit":xx  // 其中xx 代表的是每頁多少條資料
}
複製程式碼

下面我們在瀏覽器位址列輸入(或者使用 postman|postwoman|Vscode 的外掛都可) https://jsonplaceholder.typicode.com/posts

返回的結果是:

[
  {
    "userId": 1,
    "id": 1,
    "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
    "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
  },
  {
    "userId": 1,
    "id": 2,
    "title": "qui est esse",
    "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
  },
  {
    "userId": 1,
    "id": 3,
    "title": "ea molestias quasi exercitationem repellat qui ipsa sit aut",
    "body": "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit aut"
  }
]
……
複製程式碼

那我們在做上拉載入更多最重要的是,頁碼 發生變化,每次

_offset++;
複製程式碼

uni-app 網路請求 API

在官網上明確指出我們可以通過uni.request(OBJECT),其中傳入一個配置物件,值得一提的是預設是GET請求

uni.request({
  url: "https://jsonplaceholder.typicode.com/posts", //請求的地址

  success: res => {
    console.log(res);
  }
});
複製程式碼

Item 項

我們知道在前端的開發中,根據後臺的list迴圈生成item項是十分常見的業務需求,那麼隨之而來的就是上拉載入更多下拉重新整理。那麼在這個小的案例中,我們們採用卡片佈局。推薦給大家官方在維護的hello-uniapp

  • github 傳送,其中維護了有很多常見的效果。這裡我們儘量clone最新的程式碼,因為它還是更新很頻繁的,主要是為了解決一些在不同裝置的bug

20200216125554.png

Do it

  • 非同步獲取資料
	// 非同步獲取列表資料
getDataList() {
    uni.request({
        url: 'https://jsonplaceholder.typicode.com/posts', //僅為示例,並非真實介面地址。

        success: (res) => {
                console.log(res)
        }
    });
},
複製程式碼

20200216141516.png

那這樣的話是把所有的資料全部獲取來,這在實際開發中是不符合規範的

  • 引入外掛

一般我們期待在列表資料迴圈的時候,會有一個下拉重新整理以及下拉載入最好還能有回到頂部的效果,這個時候我們採取一個第三方的庫,筆者覺得還是十分好用

精緻的下拉重新整理和上拉載入 js 框架.支援 vue,完美執行於移動端和主流 PC 瀏覽器 star 數目前是2.8K

它也是可以使用在其他的開發方案中,當然了也是有uniapp的版本,在使用之前,我們先來看一段結構佈區域性分


	 <mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption" :up="upOption" >
		 <view v-for="(item,index) in dataList" :key="`item${index}`">  </view>
	 </mescroll-body>

複製程式碼

其中

屬性或方法 含義
ref="mescrollRef" 位元組跳動小程式 ref="mescrollRef" 必須配置
@init="mescrollInit" 必須配置
@down="downCallback" 必須配置
@up="upCallback" 必須配置
:down="downOption" 下拉重新整理的常用配置
:up="upOption" 上拉載入的常用配置

由於我們在一個專案的很多地方都需要使用到這個效果,那麼我們索性,全域性引入,註冊為全域性元件

// 在main.js註冊全域性元件
import MescrollBody from "@/components/mescroll-uni/mescroll-body.vue";
import MescrollUni from "@/components/mescroll-uni/mescroll-uni.vue";
Vue.component("mescroll-body", MescrollBody);
Vue.component("mescroll-uni", MescrollUni);
複製程式碼
  • pages.json 配置
{
		"path": "pages/findMovie/findMovie",
		"style": {
			"navigationBarTitleText": "找片",
			"enablePullDownRefresh": false,
			"app-plus": {
				"bounce": "none" //刪除此項: mescroll-body支援iOS回彈
			}
		}
	},
複製程式碼

其中有兩個核心的方法

方法 含義
upCallback(page) 上拉載入的回撥
downCallback() 下拉重新整理的回撥

在進行下邊部分之前,我們需要知道介面返回的資料的總頁數怎麼算,也就是說,在介面返回的資料,一般情況下會返回一個total

Math.ceil(5 / 2);
Math.ceil(26 / 10);
Math.ceil(100 / 10);
Math.ceil(20 / 4);
複製程式碼

20200216162252.png

  • 核心程式碼
/*上拉載入的回撥*/
upCallback({num,size}) {
// console.log(num,size) // 1,10
uni.request({
    url: `https://jsonplaceholder.typicode.com/posts`,
    data: {
        _offset: num,
        _limit: size
    },
    success: (data) => {
        // 介面返回的當前頁資料列表 (陣列)
        let curPageData = data.data;
        // 介面返回的當前頁資料長度 (如列表有26個資料,當前頁返回8個,則curPageLen=8)
        let curPageLen = data.data.length;
        // 介面返回的總頁數 (如列表有26個資料,每頁10條,共3頁; 則totalPage=3)
        let totalPage = Math.ceil(100/size); // 向上取正
        // 介面返回的總資料量(如列表有26個資料,每頁10條,共3頁; 則totalSize=26)
        let totalSize = 100;
        // 介面返回的是否有下一頁 (true/false)
        // let hasNext = data.xxx;

        //設定列表資料
        if (this.mescroll.num == 1) this.dataList = []; //如果是第一頁需手動置空列表
        this.dataList = this.dataList.concat(curPageData); //追加新資料

        // 請求成功,隱藏載入狀態
        //方法一(推薦): 後臺介面有返回列表的總頁數 totalPage
        this.mescroll.endByPage(curPageLen, totalPage);

        //方法二(推薦): 後臺介面有返回列表的總資料量 totalSize
        //this.mescroll.endBySize(curPageLen, totalSize);

        //方法三(推薦): 您有其他方式知道是否有下一頁 hasNext
        //this.mescroll.endSuccess(curPageLen, hasNext);
    },
    fail: () => {
        //  請求失敗,隱藏載入狀態
        this.mescroll.endErr()
    }
})
},
複製程式碼

寫在最後

關於uniapp-douban-movie 這個專案是筆者持續更新維護的一份基於 Vue 生態的多終端解決方案uniapp的個人練手專案,一些在實際開發中遇到的需求會在這個小專案梳理 有幾點特性

  • 更新時間不確定
  • 程式碼會同步 github
  • 儘可能模仿豆瓣電影的UI

模組

效果名字 其他
專案中,列表頁上拉載入更多,下拉重新整理效果

如果感覺挺好玩,不妨給個星星 程式碼同步在這裡


Although it is over, thank you

相關文章